<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha256-CTSx/A06dm1B063156EVh15m6Y67pAjZZaQc89LLSrU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.css" integrity="sha256-vQkngPS8jiHHH0I6ABTZroZk8NPZ7b+MUReOFE9UsXQ=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"rjyblog.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.18.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="LeakCanary源码详解">
<meta property="og:type" content="article">
<meta property="og:title" content="LeakCanary源码详解">
<meta property="og:url" content="https://rjyblog.gitee.io/posts/faedbb97.html">
<meta property="og:site_name" content="任建勇的博客">
<meta property="og:description" content="LeakCanary源码详解">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-09-12T07:27:58.000Z">
<meta property="article:modified_time" content="2023-10-18T02:25:18.719Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="Android">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://rjyblog.gitee.io/posts/faedbb97.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://rjyblog.gitee.io/posts/faedbb97.html","path":"posts/faedbb97.html","title":"LeakCanary源码详解"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LeakCanary源码详解 | 任建勇的博客</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">任建勇的博客</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96"><span class="nav-text">初始化</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B3%A8%E5%86%8C%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E7%9B%91%E8%A7%86%E5%99%A8"><span class="nav-text">注册内存泄漏监视器</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Activity%E6%B3%84%E6%BC%8F%E7%9B%91%E8%A7%86"><span class="nav-text">Activity泄漏监视</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Service%E6%B3%84%E6%BC%8F%E7%9B%91%E6%8E%A7"><span class="nav-text">Service泄漏监控</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#onServicePreDestroy%E8%8E%B7%E5%8F%96service%E5%AE%9E%E4%BE%8B"><span class="nav-text">onServicePreDestroy获取service实例</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#onServiceDestroyed%E7%9B%91%E6%8E%A7Service-destroy"><span class="nav-text">onServiceDestroyed监控Service destroy</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Fragment%E6%B3%84%E6%BC%8F%E7%9B%91%E6%8E%A7"><span class="nav-text">Fragment泄漏监控</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#ViewModel%E6%B3%84%E6%BC%8F%E7%9B%91%E6%8E%A7"><span class="nav-text">ViewModel泄漏监控</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#RootView%E6%B3%84%E6%BC%8F%E7%9B%91%E6%8E%A7"><span class="nav-text">RootView泄漏监控</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"><span class="nav-text">参考资料</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jason"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">Jason</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">66</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">23</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/faedbb97.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LeakCanary源码详解 | 任建勇的博客">
      <meta itemprop="description" content="LeakCanary源码详解">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LeakCanary源码详解
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-09-12 15:27:58" itemprop="dateCreated datePublished" datetime="2023-09-12T15:27:58+08:00">2023-09-12</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-10-18 10:25:18" itemprop="dateModified" datetime="2023-10-18T10:25:18+08:00">2023-10-18</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
        </span>
    </span>

  
</div>

            <div class="post-description">LeakCanary源码详解</div>
        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文基于LeakCanary 2.12进行分析。</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="635px" preserveAspectRatio="none" style="width:893px;height:635px;background:#FFFFFF;" version="1.1" viewBox="0 0 893 635" width="893px" zoomAndPan="magnify"><defs/><g><!--cluster Application--><g id="cluster_Application"><path d="M8.5,296 L102.5,296 A3.75,3.75 0 0 1 105,298.5 L112,318.2969 L251.5,318.2969 A2.5,2.5 0 0 1 254,320.7969 L254,392.5 A2.5,2.5 0 0 1 251.5,395 L8.5,395 A2.5,2.5 0 0 1 6,392.5 L6,298.5 A2.5,2.5 0 0 1 8.5,296 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="6" x2="112" y1="318.2969" y2="318.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="93" x="10" y="310.9951">Application</text></g><!--class ActivityLifecycleCallbacks--><g id="elem_ActivityLifecycleCallbacks"><rect codeLine="21" fill="#F1F1F1" height="48" id="ActivityLifecycleCallbacks" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="215" x="22.5" y="331"/><ellipse cx="37.5" cy="347" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M38.4531,343.7813 L40.1719,343.7813 C40.5625,343.7813 40.75,343.75 40.875,343.6719 C41.1406,343.5156 41.2813,343.2344 41.2813,342.9375 C41.2813,342.6719 41.1719,342.4063 40.9375,342.2344 C40.7656,342.125 40.625,342.0938 40.1719,342.0938 L35.0313,342.0938 C34.5938,342.0938 34.4688,342.1094 34.3125,342.2031 C34.0625,342.3594 33.9063,342.6563 33.9063,342.9375 C33.9063,343.2188 34.0469,343.4688 34.2656,343.6406 C34.4219,343.75 34.6094,343.7813 35.0313,343.7813 L36.75,343.7813 L36.75,350.2969 L35.0313,350.2969 C34.5938,350.2969 34.4688,350.3125 34.3125,350.4219 C34.0625,350.5781 33.9063,350.8594 33.9063,351.1563 C33.9063,351.4063 34.0469,351.6719 34.2656,351.8281 C34.4219,351.9531 34.625,352 35.0313,352 L40.1719,352 C40.9219,352 41.2813,351.7188 41.2813,351.1563 C41.2813,350.875 41.1719,350.625 40.9375,350.4531 C40.7656,350.3281 40.625,350.2969 40.1719,350.2969 L38.4531,350.2969 L38.4531,343.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="183" x="51.5" y="351.8467">ActivityLifecycleCallbacks</text><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="236.5" y1="363" y2="363"/><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="236.5" y1="371" y2="371"/></g><!--class ReachabilityWatcher--><g id="elem_ReachabilityWatcher"><rect codeLine="1" fill="#F1F1F1" height="48" id="ReachabilityWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="180" x="369" y="331"/><ellipse cx="384" cy="347" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M384.9531,343.7813 L386.6719,343.7813 C387.0625,343.7813 387.25,343.75 387.375,343.6719 C387.6406,343.5156 387.7813,343.2344 387.7813,342.9375 C387.7813,342.6719 387.6719,342.4063 387.4375,342.2344 C387.2656,342.125 387.125,342.0938 386.6719,342.0938 L381.5313,342.0938 C381.0938,342.0938 380.9688,342.1094 380.8125,342.2031 C380.5625,342.3594 380.4063,342.6563 380.4063,342.9375 C380.4063,343.2188 380.5469,343.4688 380.7656,343.6406 C380.9219,343.75 381.1094,343.7813 381.5313,343.7813 L383.25,343.7813 L383.25,350.2969 L381.5313,350.2969 C381.0938,350.2969 380.9688,350.3125 380.8125,350.4219 C380.5625,350.5781 380.4063,350.8594 380.4063,351.1563 C380.4063,351.4063 380.5469,351.6719 380.7656,351.8281 C380.9219,351.9531 381.125,352 381.5313,352 L386.6719,352 C387.4219,352 387.7813,351.7188 387.7813,351.1563 C387.7813,350.875 387.6719,350.625 387.4375,350.4531 C387.2656,350.3281 387.125,350.2969 386.6719,350.2969 L384.9531,350.2969 L384.9531,343.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="148" x="398" y="351.8467">ReachabilityWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="370" x2="548" y1="363" y2="363"/><line style="stroke:#181818;stroke-width:0.5;" x1="370" x2="548" y1="371" y2="371"/></g><!--class ObjectWatcher--><g id="elem_ObjectWatcher"><rect codeLine="3" fill="#F1F1F1" height="80.5938" id="ObjectWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="406" x="256" y="439"/><ellipse cx="399.75" cy="455" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M402.0938,450.6719 C401.1563,450.2344 400.5625,450.0938 399.6875,450.0938 C397.0625,450.0938 395.0625,452.1719 395.0625,454.8906 L395.0625,456.0156 C395.0625,458.5938 397.1719,460.4844 400.0625,460.4844 C401.2813,460.4844 402.4375,460.1875 403.1875,459.6406 C403.7656,459.2344 404.0938,458.7813 404.0938,458.3906 C404.0938,457.9375 403.7031,457.5469 403.2344,457.5469 C403.0156,457.5469 402.8125,457.625 402.625,457.8125 C402.1719,458.2969 402.1719,458.2969 401.9844,458.3906 C401.5625,458.6563 400.875,458.7813 400.1094,458.7813 C398.0625,458.7813 396.7656,457.6875 396.7656,455.9844 L396.7656,454.8906 C396.7656,453.1094 398.0156,451.7969 399.75,451.7969 C400.3281,451.7969 400.9375,451.9531 401.4063,452.2031 C401.8906,452.4844 402.0625,452.7031 402.1563,453.1094 C402.2188,453.5156 402.25,453.6406 402.3906,453.7656 C402.5313,453.9063 402.7656,454.0156 402.9844,454.0156 C403.25,454.0156 403.5156,453.875 403.6875,453.6563 C403.7969,453.5 403.8281,453.3125 403.8281,452.8906 L403.8281,451.4688 C403.8281,451.0313 403.8125,450.9063 403.7188,450.75 C403.5625,450.4844 403.2813,450.3438 402.9844,450.3438 C402.6875,450.3438 402.4844,450.4375 402.2656,450.75 L402.0938,450.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="110" x="420.25" y="459.8467">ObjectWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="257" x2="661" y1="471" y2="471"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="394" x="262" y="487.9951">watchedObjects : Map&lt;String, KeyedWeakReference&gt;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="225" x="262" y="504.292">queue : ReferenceQueue&lt;Any&gt;</text><line style="stroke:#181818;stroke-width:0.5;" x1="257" x2="661" y1="511.5938" y2="511.5938"/></g><!--class KeyedWeakReference--><g id="elem_KeyedWeakReference"><rect fill="#F1F1F1" height="48" id="KeyedWeakReference" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="192" x="519" y="580"/><ellipse cx="534" cy="596" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M536.3438,591.6719 C535.4063,591.2344 534.8125,591.0938 533.9375,591.0938 C531.3125,591.0938 529.3125,593.1719 529.3125,595.8906 L529.3125,597.0156 C529.3125,599.5938 531.4219,601.4844 534.3125,601.4844 C535.5313,601.4844 536.6875,601.1875 537.4375,600.6406 C538.0156,600.2344 538.3438,599.7813 538.3438,599.3906 C538.3438,598.9375 537.9531,598.5469 537.4844,598.5469 C537.2656,598.5469 537.0625,598.625 536.875,598.8125 C536.4219,599.2969 536.4219,599.2969 536.2344,599.3906 C535.8125,599.6563 535.125,599.7813 534.3594,599.7813 C532.3125,599.7813 531.0156,598.6875 531.0156,596.9844 L531.0156,595.8906 C531.0156,594.1094 532.2656,592.7969 534,592.7969 C534.5781,592.7969 535.1875,592.9531 535.6563,593.2031 C536.1406,593.4844 536.3125,593.7031 536.4063,594.1094 C536.4688,594.5156 536.5,594.6406 536.6406,594.7656 C536.7813,594.9063 537.0156,595.0156 537.2344,595.0156 C537.5,595.0156 537.7656,594.875 537.9375,594.6563 C538.0469,594.5 538.0781,594.3125 538.0781,593.8906 L538.0781,592.4688 C538.0781,592.0313 538.0625,591.9063 537.9688,591.75 C537.8125,591.4844 537.5313,591.3438 537.2344,591.3438 C536.9375,591.3438 536.7344,591.4375 536.5156,591.75 L536.3438,591.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="160" x="548" y="600.8467">KeyedWeakReference</text><line style="stroke:#181818;stroke-width:0.5;" x1="520" x2="710" y1="612" y2="612"/><line style="stroke:#181818;stroke-width:0.5;" x1="520" x2="710" y1="620" y2="620"/></g><!--class WeakReference--><g id="elem_WeakReference"><rect fill="#F1F1F1" height="48" id="WeakReference" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="147" x="697.5" y="455.5"/><ellipse cx="712.5" cy="471.5" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M714.8438,467.1719 C713.9063,466.7344 713.3125,466.5938 712.4375,466.5938 C709.8125,466.5938 707.8125,468.6719 707.8125,471.3906 L707.8125,472.5156 C707.8125,475.0938 709.9219,476.9844 712.8125,476.9844 C714.0313,476.9844 715.1875,476.6875 715.9375,476.1406 C716.5156,475.7344 716.8438,475.2813 716.8438,474.8906 C716.8438,474.4375 716.4531,474.0469 715.9844,474.0469 C715.7656,474.0469 715.5625,474.125 715.375,474.3125 C714.9219,474.7969 714.9219,474.7969 714.7344,474.8906 C714.3125,475.1563 713.625,475.2813 712.8594,475.2813 C710.8125,475.2813 709.5156,474.1875 709.5156,472.4844 L709.5156,471.3906 C709.5156,469.6094 710.7656,468.2969 712.5,468.2969 C713.0781,468.2969 713.6875,468.4531 714.1563,468.7031 C714.6406,468.9844 714.8125,469.2031 714.9063,469.6094 C714.9688,470.0156 715,470.1406 715.1406,470.2656 C715.2813,470.4063 715.5156,470.5156 715.7344,470.5156 C716,470.5156 716.2656,470.375 716.4375,470.1563 C716.5469,470 716.5781,469.8125 716.5781,469.3906 L716.5781,467.9688 C716.5781,467.5313 716.5625,467.4063 716.4688,467.25 C716.3125,466.9844 716.0313,466.8438 715.7344,466.8438 C715.4375,466.8438 715.2344,466.9375 715.0156,467.25 L714.8438,467.1719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="115" x="726.5" y="476.3467">WeakReference</text><line style="stroke:#181818;stroke-width:0.5;" x1="698.5" x2="843.5" y1="487.5" y2="487.5"/><line style="stroke:#181818;stroke-width:0.5;" x1="698.5" x2="843.5" y1="495.5" y2="495.5"/></g><!--class InstallableWatcher--><g id="elem_InstallableWatcher"><rect codeLine="10" fill="#F1F1F1" height="48" id="InstallableWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="165" x="351.5" y="115"/><ellipse cx="366.5" cy="131" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M367.4531,127.7813 L369.1719,127.7813 C369.5625,127.7813 369.75,127.75 369.875,127.6719 C370.1406,127.5156 370.2813,127.2344 370.2813,126.9375 C370.2813,126.6719 370.1719,126.4063 369.9375,126.2344 C369.7656,126.125 369.625,126.0938 369.1719,126.0938 L364.0313,126.0938 C363.5938,126.0938 363.4688,126.1094 363.3125,126.2031 C363.0625,126.3594 362.9063,126.6563 362.9063,126.9375 C362.9063,127.2188 363.0469,127.4688 363.2656,127.6406 C363.4219,127.75 363.6094,127.7813 364.0313,127.7813 L365.75,127.7813 L365.75,134.2969 L364.0313,134.2969 C363.5938,134.2969 363.4688,134.3125 363.3125,134.4219 C363.0625,134.5781 362.9063,134.8594 362.9063,135.1563 C362.9063,135.4063 363.0469,135.6719 363.2656,135.8281 C363.4219,135.9531 363.625,136 364.0313,136 L369.1719,136 C369.9219,136 370.2813,135.7188 370.2813,135.1563 C370.2813,134.875 370.1719,134.625 369.9375,134.4531 C369.7656,134.3281 369.625,134.2969 369.1719,134.2969 L367.4531,134.2969 L367.4531,127.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="133" x="380.5" y="135.8467">InstallableWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="352.5" x2="515.5" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="352.5" x2="515.5" y1="155" y2="155"/></g><!--class ActivityWatcher--><g id="elem_ActivityWatcher"><rect fill="#F1F1F1" height="48" id="ActivityWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="149" x="55.5" y="223"/><ellipse cx="70.5" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M72.8438,234.6719 C71.9063,234.2344 71.3125,234.0938 70.4375,234.0938 C67.8125,234.0938 65.8125,236.1719 65.8125,238.8906 L65.8125,240.0156 C65.8125,242.5938 67.9219,244.4844 70.8125,244.4844 C72.0313,244.4844 73.1875,244.1875 73.9375,243.6406 C74.5156,243.2344 74.8438,242.7813 74.8438,242.3906 C74.8438,241.9375 74.4531,241.5469 73.9844,241.5469 C73.7656,241.5469 73.5625,241.625 73.375,241.8125 C72.9219,242.2969 72.9219,242.2969 72.7344,242.3906 C72.3125,242.6563 71.625,242.7813 70.8594,242.7813 C68.8125,242.7813 67.5156,241.6875 67.5156,239.9844 L67.5156,238.8906 C67.5156,237.1094 68.7656,235.7969 70.5,235.7969 C71.0781,235.7969 71.6875,235.9531 72.1563,236.2031 C72.6406,236.4844 72.8125,236.7031 72.9063,237.1094 C72.9688,237.5156 73,237.6406 73.1406,237.7656 C73.2813,237.9063 73.5156,238.0156 73.7344,238.0156 C74,238.0156 74.2656,237.875 74.4375,237.6563 C74.5469,237.5 74.5781,237.3125 74.5781,236.8906 L74.5781,235.4688 C74.5781,235.0313 74.5625,234.9063 74.4688,234.75 C74.3125,234.4844 74.0313,234.3438 73.7344,234.3438 C73.4375,234.3438 73.2344,234.4375 73.0156,234.75 L72.8438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="84.5" y="243.8467">ActivityWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="56.5" x2="203.5" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="56.5" x2="203.5" y1="263" y2="263"/></g><!--class FragmentAndViewModelWatcher--><g id="elem_FragmentAndViewModelWatcher"><rect fill="#F1F1F1" height="48" id="FragmentAndViewModelWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="268" x="421" y="223"/><ellipse cx="436" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M438.3438,234.6719 C437.4063,234.2344 436.8125,234.0938 435.9375,234.0938 C433.3125,234.0938 431.3125,236.1719 431.3125,238.8906 L431.3125,240.0156 C431.3125,242.5938 433.4219,244.4844 436.3125,244.4844 C437.5313,244.4844 438.6875,244.1875 439.4375,243.6406 C440.0156,243.2344 440.3438,242.7813 440.3438,242.3906 C440.3438,241.9375 439.9531,241.5469 439.4844,241.5469 C439.2656,241.5469 439.0625,241.625 438.875,241.8125 C438.4219,242.2969 438.4219,242.2969 438.2344,242.3906 C437.8125,242.6563 437.125,242.7813 436.3594,242.7813 C434.3125,242.7813 433.0156,241.6875 433.0156,239.9844 L433.0156,238.8906 C433.0156,237.1094 434.2656,235.7969 436,235.7969 C436.5781,235.7969 437.1875,235.9531 437.6563,236.2031 C438.1406,236.4844 438.3125,236.7031 438.4063,237.1094 C438.4688,237.5156 438.5,237.6406 438.6406,237.7656 C438.7813,237.9063 439.0156,238.0156 439.2344,238.0156 C439.5,238.0156 439.7656,237.875 439.9375,237.6563 C440.0469,237.5 440.0781,237.3125 440.0781,236.8906 L440.0781,235.4688 C440.0781,235.0313 440.0625,234.9063 439.9688,234.75 C439.8125,234.4844 439.5313,234.3438 439.2344,234.3438 C438.9375,234.3438 438.7344,234.4375 438.5156,234.75 L438.3438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="236" x="450" y="243.8467">FragmentAndViewModelWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="422" x2="688" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="422" x2="688" y1="263" y2="263"/></g><!--class RootViewWatcher--><g id="elem_RootViewWatcher"><rect fill="#F1F1F1" height="48" id="RootViewWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="162" x="724" y="223"/><ellipse cx="739" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M741.3438,234.6719 C740.4063,234.2344 739.8125,234.0938 738.9375,234.0938 C736.3125,234.0938 734.3125,236.1719 734.3125,238.8906 L734.3125,240.0156 C734.3125,242.5938 736.4219,244.4844 739.3125,244.4844 C740.5313,244.4844 741.6875,244.1875 742.4375,243.6406 C743.0156,243.2344 743.3438,242.7813 743.3438,242.3906 C743.3438,241.9375 742.9531,241.5469 742.4844,241.5469 C742.2656,241.5469 742.0625,241.625 741.875,241.8125 C741.4219,242.2969 741.4219,242.2969 741.2344,242.3906 C740.8125,242.6563 740.125,242.7813 739.3594,242.7813 C737.3125,242.7813 736.0156,241.6875 736.0156,239.9844 L736.0156,238.8906 C736.0156,237.1094 737.2656,235.7969 739,235.7969 C739.5781,235.7969 740.1875,235.9531 740.6563,236.2031 C741.1406,236.4844 741.3125,236.7031 741.4063,237.1094 C741.4688,237.5156 741.5,237.6406 741.6406,237.7656 C741.7813,237.9063 742.0156,238.0156 742.2344,238.0156 C742.5,238.0156 742.7656,237.875 742.9375,237.6563 C743.0469,237.5 743.0781,237.3125 743.0781,236.8906 L743.0781,235.4688 C743.0781,235.0313 743.0625,234.9063 742.9688,234.75 C742.8125,234.4844 742.5313,234.3438 742.2344,234.3438 C741.9375,234.3438 741.7344,234.4375 741.5156,234.75 L741.3438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="130" x="753" y="243.8467">RootViewWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="725" x2="885" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="725" x2="885" y1="263" y2="263"/></g><!--class ServiceWatcher--><g id="elem_ServiceWatcher"><rect fill="#F1F1F1" height="48" id="ServiceWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="146" x="240" y="223"/><ellipse cx="255" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M257.3438,234.6719 C256.4063,234.2344 255.8125,234.0938 254.9375,234.0938 C252.3125,234.0938 250.3125,236.1719 250.3125,238.8906 L250.3125,240.0156 C250.3125,242.5938 252.4219,244.4844 255.3125,244.4844 C256.5313,244.4844 257.6875,244.1875 258.4375,243.6406 C259.0156,243.2344 259.3438,242.7813 259.3438,242.3906 C259.3438,241.9375 258.9531,241.5469 258.4844,241.5469 C258.2656,241.5469 258.0625,241.625 257.875,241.8125 C257.4219,242.2969 257.4219,242.2969 257.2344,242.3906 C256.8125,242.6563 256.125,242.7813 255.3594,242.7813 C253.3125,242.7813 252.0156,241.6875 252.0156,239.9844 L252.0156,238.8906 C252.0156,237.1094 253.2656,235.7969 255,235.7969 C255.5781,235.7969 256.1875,235.9531 256.6563,236.2031 C257.1406,236.4844 257.3125,236.7031 257.4063,237.1094 C257.4688,237.5156 257.5,237.6406 257.6406,237.7656 C257.7813,237.9063 258.0156,238.0156 258.2344,238.0156 C258.5,238.0156 258.7656,237.875 258.9375,237.6563 C259.0469,237.5 259.0781,237.3125 259.0781,236.8906 L259.0781,235.4688 C259.0781,235.0313 259.0625,234.9063 258.9688,234.75 C258.8125,234.4844 258.5313,234.3438 258.2344,234.3438 C257.9375,234.3438 257.7344,234.4375 257.5156,234.75 L257.3438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="114" x="269" y="243.8467">ServiceWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="241" x2="385" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="241" x2="385" y1="263" y2="263"/></g><!--class AppWatcher--><g id="elem_AppWatcher"><rect fill="#F1F1F1" height="48" id="AppWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="123" x="372.5" y="7"/><ellipse cx="387.5" cy="23" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M389.8438,18.6719 C388.9063,18.2344 388.3125,18.0938 387.4375,18.0938 C384.8125,18.0938 382.8125,20.1719 382.8125,22.8906 L382.8125,24.0156 C382.8125,26.5938 384.9219,28.4844 387.8125,28.4844 C389.0313,28.4844 390.1875,28.1875 390.9375,27.6406 C391.5156,27.2344 391.8438,26.7813 391.8438,26.3906 C391.8438,25.9375 391.4531,25.5469 390.9844,25.5469 C390.7656,25.5469 390.5625,25.625 390.375,25.8125 C389.9219,26.2969 389.9219,26.2969 389.7344,26.3906 C389.3125,26.6563 388.625,26.7813 387.8594,26.7813 C385.8125,26.7813 384.5156,25.6875 384.5156,23.9844 L384.5156,22.8906 C384.5156,21.1094 385.7656,19.7969 387.5,19.7969 C388.0781,19.7969 388.6875,19.9531 389.1563,20.2031 C389.6406,20.4844 389.8125,20.7031 389.9063,21.1094 C389.9688,21.5156 390,21.6406 390.1406,21.7656 C390.2813,21.9063 390.5156,22.0156 390.7344,22.0156 C391,22.0156 391.2656,21.875 391.4375,21.6563 C391.5469,21.5 391.5781,21.3125 391.5781,20.8906 L391.5781,19.4688 C391.5781,19.0313 391.5625,18.9063 391.4688,18.75 C391.3125,18.4844 391.0313,18.3438 390.7344,18.3438 C390.4375,18.3438 390.2344,18.4375 390.0156,18.75 L389.8438,18.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="91" x="401.5" y="27.8467">AppWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="373.5" x2="494.5" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="373.5" x2="494.5" y1="47" y2="47"/></g><!--reverse link ReachabilityWatcher to ObjectWatcher--><g id="link_ReachabilityWatcher_ObjectWatcher"><path codeLine="2" d="M459,397.041 C459,413.814 459,418.95 459,438.688 " fill="none" id="ReachabilityWatcher-backto-ObjectWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="459,379.041,453,397.041,465,397.041,459,379.041" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ObjectWatcher to KeyedWeakReference--><g id="link_ObjectWatcher_KeyedWeakReference"><path codeLine="7" d="M519.0868,527.6833 C544.1748,547.3845 564.149,563.0687 585.51,579.8428 " fill="none" id="ObjectWatcher-backto-KeyedWeakReference" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="509.649,520.272,511.8974,527.1236,519.0868,527.6833,516.8383,520.8317,509.649,520.272" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="508.7921" y="539.7718">1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="568.9282" y="568.8146">n</text></g><!--reverse link WeakReference to KeyedWeakReference--><g id="link_WeakReference_KeyedWeakReference"><path codeLine="8" d="M727.5012,514.6579 C699.6992,536.4899 672.321,557.988 644.476,579.8541 " fill="none" id="WeakReference-backto-KeyedWeakReference" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="741.658,503.541,723.7956,509.9389,731.2068,519.3768,741.658,503.541" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link InstallableWatcher to ActivityWatcher--><g id="link_InstallableWatcher_ActivityWatcher"><path codeLine="11" d="M351.0406,168.9266 C300.1366,186.6766 247.034,205.192 196.097,222.953 " fill="none" id="InstallableWatcher-backto-ActivityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="368.037,163,349.0651,163.2611,353.0162,174.592,368.037,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link InstallableWatcher to FragmentAndViewModelWatcher--><g id="link_InstallableWatcher_FragmentAndViewModelWatcher"><path codeLine="12" d="M473.7945,174.8609 C493.9515,192.5189 508.131,204.941 528.378,222.678 " fill="none" id="InstallableWatcher-backto-FragmentAndViewModelWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="460.255,163,469.8409,179.3741,477.7482,170.3478,460.255,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link InstallableWatcher to RootViewWatcher--><g id="link_InstallableWatcher_RootViewWatcher"><path codeLine="13" d="M531.8084,167.9451 C593.9314,185.6951 662.173,205.192 724.336,222.953 " fill="none" id="InstallableWatcher-backto-RootViewWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="514.501,163,530.16,173.7143,533.4568,162.176,514.501,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link InstallableWatcher to ServiceWatcher--><g id="link_InstallableWatcher_ServiceWatcher"><path codeLine="14" d="M394.2055,174.8609 C374.0485,192.5189 359.869,204.941 339.622,222.678 " fill="none" id="InstallableWatcher-backto-ServiceWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="407.745,163,390.2518,170.3478,398.1591,179.3741,407.745,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ActivityWatcher to ReachabilityWatcher--><g id="link_ActivityWatcher_ReachabilityWatcher"><path codeLine="16" d="M212.8098,274.6801 C267.8998,292.4301 332.342,313.192 387.468,330.953 " fill="none" id="ActivityWatcher-backto-ReachabilityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="201.388,271,205.8722,276.6473,212.8098,274.6801,208.3256,269.0328,201.388,271" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link FragmentAndViewModelWatcher to ReachabilityWatcher--><g id="link_FragmentAndViewModelWatcher_ReachabilityWatcher"><path codeLine="17" d="M526.1137,279.8945 C510.1217,297.5525 496.186,312.941 480.121,330.678 " fill="none" id="FragmentAndViewModelWatcher-backto-ReachabilityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="534.169,271,527.1765,272.7621,526.1137,279.8945,533.1062,278.1323,534.169,271" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link RootViewWatcher to ReachabilityWatcher--><g id="link_RootViewWatcher_ReachabilityWatcher"><path codeLine="18" d="M718.4494,274.5152 C660.5134,292.2652 592.203,313.192 534.228,330.953 " fill="none" id="RootViewWatcher-backto-ReachabilityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="729.923,271,723.0145,268.9331,718.4494,274.5152,725.3579,276.5821,729.923,271" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ServiceWatcher to ReachabilityWatcher--><g id="link_ServiceWatcher_ReachabilityWatcher"><path codeLine="19" d="M354.3905,278.0502 C378.7955,295.7692 402.678,313.108 427.13,330.862 " fill="none" id="ServiceWatcher-backto-ReachabilityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="344.68,271,347.1852,277.762,354.3905,278.0502,351.8853,271.2883,344.68,271" style="stroke:#181818;stroke-width:1.0;"/></g><!--link ActivityWatcher to ActivityLifecycleCallbacks--><g id="link_ActivityWatcher_ActivityLifecycleCallbacks"><path codeLine="22" d="M130,271 C130,288.658 130,306.941 130,324.678 " fill="none" id="ActivityWatcher-to-ActivityLifecycleCallbacks" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="130,330.678,134,321.678,130,325.678,126,321.678,130,330.678" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link AppWatcher to InstallableWatcher--><g id="link_AppWatcher_InstallableWatcher"><path codeLine="24" d="M434,67 C434,84.658 434,96.941 434,114.678 " fill="none" id="AppWatcher-backto-InstallableWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="434,55,430,61,434,67,438,61,434,55" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="424.975" y="75.1558">1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="425.025" y="104.0045">n</text></g><!--link AppWatcher to ActivityWatcher--><g id="link_AppWatcher_ActivityWatcher"><path codeLine="25" d="M398.742,55.07 C373.789,71.525 339.631,94.313 310,115 C257.077,151.949 201.4206,192.8625 165.7676,219.3305 " fill="none" id="AppWatcher-to-ActivityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="160.95,222.907,170.5607,220.754,164.9646,219.9266,165.792,214.3306,160.95,222.907" style="stroke:#181818;stroke-width:1.0;"/></g><!--link AppWatcher to FragmentAndViewModelWatcher--><g id="link_AppWatcher_FragmentAndViewModelWatcher"><path codeLine="26" d="M473.769,55.028 C495.078,69.491 519.8,90.112 534,115 C553.291,148.81 556.3093,189.0712 556.1013,216.6092 " fill="none" id="AppWatcher-to-FragmentAndViewModelWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="556.056,222.609,560.1239,213.6395,556.0938,217.6091,552.1241,213.579,556.056,222.609" style="stroke:#181818;stroke-width:1.0;"/></g><!--link AppWatcher to RootViewWatcher--><g id="link_AppWatcher_RootViewWatcher"><path codeLine="27" d="M474.056,55.105 C545.443,96.283 688.6477,178.886 759.9137,219.994 " fill="none" id="AppWatcher-to-RootViewWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="765.111,222.992,759.3136,215.0302,760.7799,220.4937,755.3164,221.96,765.111,222.992" style="stroke:#181818;stroke-width:1.0;"/></g><!--link AppWatcher to ServiceWatcher--><g id="link_AppWatcher_ServiceWatcher"><path codeLine="28" d="M394.231,55.028 C372.922,69.491 348.2,90.112 334,115 C314.709,148.81 311.6907,189.0712 311.8987,216.6092 " fill="none" id="AppWatcher-to-ServiceWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="311.944,222.609,315.8759,213.579,311.9062,217.6091,307.8761,213.6395,311.944,222.609" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[ZPBHQuCm4CRVyrS47ySSx7M888F1sCgOXVNvFCysQnPTJ5jas_y-goWcZMrzoztlak- -Jw4CwGAGU4g06yY45APPWS4DQUQfyUWt3FbRzabe1WmbrBLTup-Cjz-XE-Lzg-OFV05Lj3HQgFKjVw66yXN1DgM2D2cak1lwtj6EMdOilnyBKQAQcFqn-vdWFk0thQ101Pxxc7NgfNie9aONdbLjG4h890tRdPRwYn8qOZynQuvxqh3-8cKIbNy8EYpAdEIbcRGipH6-n2r9xmMEKfcZgRF65-mPJRCpZgPPpjOqYqrCJwfA2WGZIdKtRF0g2i869JssUsU0s_fakJ2ChnrbBUVxPJnnJyZk0ITbftqkN0TrCtNQjct_]--></g></svg>

<h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2><p>引入LeakCanary时，只需要引入maven库的坐标即可，如下：</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">dependencies</span> &#123;</span><br><span class="line">  <span class="comment">// debugImplementation because LeakCanary should only run in debug builds.</span></span><br><span class="line">  debugImplementation <span class="string">&#x27;com.squareup.leakcanary:leakcanary-android:2.12&#x27;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>而不需要进行任何的代码改动就可以使用LeakCanary了。另外，引入leakcanary时使用的是debugImplementation表示只在debug版本中才会集成leakcanary，release版本不会集成。</p>
<p>那么，leakcanary如何完成初始化呢？</p>
<p>leakcanary使用了<code>ContentProvider</code>来进行初始化，当app启动时系统会自动初始化注册的ContentProvider。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">application</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">provider</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:name</span>=<span class="string">&quot;leakcanary.internal.MainProcessAppWatcherInstaller&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:authorities</span>=<span class="string">&quot;$&#123;applicationId&#125;.leakcanary-installer&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:enabled</span>=<span class="string">&quot;@bool/leak_canary_watcher_auto_install&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:exported</span>=<span class="string">&quot;false&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">application</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">internal</span> <span class="keyword">class</span> <span class="title class_">MainProcessAppWatcherInstaller</span> : <span class="type">ContentProvider</span>() &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">()</span></span>: <span class="built_in">Boolean</span> &#123;</span><br><span class="line">    <span class="keyword">val</span> application = context!!.applicationContext <span class="keyword">as</span> Application</span><br><span class="line">    AppWatcher.manualInstall(application)</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">  &#125;</span><br><span class="line">  ......</span><br></pre></td></tr></table></figure>

<p>系统初始化ContentProvider的时机在Application之前，即<code>ContentProvider#onCreate</code>先于<code>Application#onCreate</code>来执行，但此时Application的实例已经存在了。</p>
<h3 id="注册内存泄漏监视器"><a href="#注册内存泄漏监视器" class="headerlink" title="注册内存泄漏监视器"></a>注册内存泄漏监视器</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">manualInstall</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  application: <span class="type">Application</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">  retainedDelayMillis: <span class="type">Long</span> = TimeUnit.SECONDS.toMillis(<span class="number">5</span>)</span></span>,</span><br><span class="line">  watchersToInstall: List&lt;InstallableWatcher&gt; = appDefaultWatchers(application)</span><br><span class="line">) &#123;</span><br><span class="line">  checkMainThread()</span><br><span class="line">  <span class="keyword">if</span> (isInstalled) &#123;</span><br><span class="line">    <span class="keyword">throw</span> IllegalStateException(</span><br><span class="line">      <span class="string">&quot;AppWatcher already installed, see exception cause for prior install call&quot;</span>, installCause</span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">  check(retainedDelayMillis &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">    <span class="string">&quot;retainedDelayMillis <span class="variable">$retainedDelayMillis</span> must be at least 0 ms&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">this</span>.retainedDelayMillis = retainedDelayMillis</span><br><span class="line">  <span class="keyword">if</span> (application.isDebuggableBuild) &#123;</span><br><span class="line">    LogcatSharkLog.install()</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// Requires AppWatcher.objectWatcher to be set</span></span><br><span class="line">  LeakCanaryDelegate.loadLeakCanary(application)</span><br><span class="line"></span><br><span class="line">  watchersToInstall.forEach &#123;</span><br><span class="line">    it.install()</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// Only install after we&#x27;re fully done with init.</span></span><br><span class="line">  installCause = RuntimeException(<span class="string">&quot;manualInstall() first called here&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">appDefaultWatchers</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  application: <span class="type">Application</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">  reachabilityWatcher: <span class="type">ReachabilityWatcher</span> = objectWatcher</span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span>: List&lt;InstallableWatcher&gt; &#123;</span><br><span class="line">  <span class="keyword">return</span> listOf(</span><br><span class="line">    ActivityWatcher(application, reachabilityWatcher), <span class="comment">//Activity内存泄漏监视器</span></span><br><span class="line">    FragmentAndViewModelWatcher(application, reachabilityWatcher), <span class="comment">//Fragment和ViewModel内存泄漏监视器</span></span><br><span class="line">    RootViewWatcher(reachabilityWatcher), <span class="comment">//RootView内存泄漏监视器</span></span><br><span class="line">    ServiceWatcher(reachabilityWatcher) <span class="comment">//服务内存泄漏监视器</span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Activity泄漏监视"><a href="#Activity泄漏监视" class="headerlink" title="Activity泄漏监视"></a>Activity泄漏监视</h2><p>Activity的内存泄漏通过ActivityWatcher来监控。下图是Activity泄漏监控相关类图结构：</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="682px" preserveAspectRatio="none" style="width:900px;height:682px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 682" width="900px" zoomAndPan="magnify"><defs/><g><!--class ReachabilityWatcher--><g id="elem_ReachabilityWatcher"><rect codeLine="1" fill="#F1F1F1" height="48" id="ReachabilityWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="180" x="191.5" y="7"/><ellipse cx="206.5" cy="23" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M207.4531,19.7813 L209.1719,19.7813 C209.5625,19.7813 209.75,19.75 209.875,19.6719 C210.1406,19.5156 210.2813,19.2344 210.2813,18.9375 C210.2813,18.6719 210.1719,18.4063 209.9375,18.2344 C209.7656,18.125 209.625,18.0938 209.1719,18.0938 L204.0313,18.0938 C203.5938,18.0938 203.4688,18.1094 203.3125,18.2031 C203.0625,18.3594 202.9063,18.6563 202.9063,18.9375 C202.9063,19.2188 203.0469,19.4688 203.2656,19.6406 C203.4219,19.75 203.6094,19.7813 204.0313,19.7813 L205.75,19.7813 L205.75,26.2969 L204.0313,26.2969 C203.5938,26.2969 203.4688,26.3125 203.3125,26.4219 C203.0625,26.5781 202.9063,26.8594 202.9063,27.1563 C202.9063,27.4063 203.0469,27.6719 203.2656,27.8281 C203.4219,27.9531 203.625,28 204.0313,28 L209.1719,28 C209.9219,28 210.2813,27.7188 210.2813,27.1563 C210.2813,26.875 210.1719,26.625 209.9375,26.4531 C209.7656,26.3281 209.625,26.2969 209.1719,26.2969 L207.4531,26.2969 L207.4531,19.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="148" x="220.5" y="27.8467">ReachabilityWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="192.5" x2="370.5" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="192.5" x2="370.5" y1="47" y2="47"/></g><!--class ActivityWatcher--><g id="elem_ActivityWatcher"><rect fill="#F1F1F1" height="48" id="ActivityWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="149" x="7" y="7"/><ellipse cx="22" cy="23" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M24.3438,18.6719 C23.4063,18.2344 22.8125,18.0938 21.9375,18.0938 C19.3125,18.0938 17.3125,20.1719 17.3125,22.8906 L17.3125,24.0156 C17.3125,26.5938 19.4219,28.4844 22.3125,28.4844 C23.5313,28.4844 24.6875,28.1875 25.4375,27.6406 C26.0156,27.2344 26.3438,26.7813 26.3438,26.3906 C26.3438,25.9375 25.9531,25.5469 25.4844,25.5469 C25.2656,25.5469 25.0625,25.625 24.875,25.8125 C24.4219,26.2969 24.4219,26.2969 24.2344,26.3906 C23.8125,26.6563 23.125,26.7813 22.3594,26.7813 C20.3125,26.7813 19.0156,25.6875 19.0156,23.9844 L19.0156,22.8906 C19.0156,21.1094 20.2656,19.7969 22,19.7969 C22.5781,19.7969 23.1875,19.9531 23.6563,20.2031 C24.1406,20.4844 24.3125,20.7031 24.4063,21.1094 C24.4688,21.5156 24.5,21.6406 24.6406,21.7656 C24.7813,21.9063 25.0156,22.0156 25.2344,22.0156 C25.5,22.0156 25.7656,21.875 25.9375,21.6563 C26.0469,21.5 26.0781,21.3125 26.0781,20.8906 L26.0781,19.4688 C26.0781,19.0313 26.0625,18.9063 25.9688,18.75 C25.8125,18.4844 25.5313,18.3438 25.2344,18.3438 C24.9375,18.3438 24.7344,18.4375 24.5156,18.75 L24.3438,18.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="36" y="27.8467">ActivityWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="155" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="155" y1="47" y2="47"/></g><!--class ObjectWatcher--><g id="elem_ObjectWatcher"><rect fill="#F1F1F1" height="48" id="ObjectWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="142" x="210.5" y="123"/><ellipse cx="225.5" cy="139" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M227.8438,134.6719 C226.9063,134.2344 226.3125,134.0938 225.4375,134.0938 C222.8125,134.0938 220.8125,136.1719 220.8125,138.8906 L220.8125,140.0156 C220.8125,142.5938 222.9219,144.4844 225.8125,144.4844 C227.0313,144.4844 228.1875,144.1875 228.9375,143.6406 C229.5156,143.2344 229.8438,142.7813 229.8438,142.3906 C229.8438,141.9375 229.4531,141.5469 228.9844,141.5469 C228.7656,141.5469 228.5625,141.625 228.375,141.8125 C227.9219,142.2969 227.9219,142.2969 227.7344,142.3906 C227.3125,142.6563 226.625,142.7813 225.8594,142.7813 C223.8125,142.7813 222.5156,141.6875 222.5156,139.9844 L222.5156,138.8906 C222.5156,137.1094 223.7656,135.7969 225.5,135.7969 C226.0781,135.7969 226.6875,135.9531 227.1563,136.2031 C227.6406,136.4844 227.8125,136.7031 227.9063,137.1094 C227.9688,137.5156 228,137.6406 228.1406,137.7656 C228.2813,137.9063 228.5156,138.0156 228.7344,138.0156 C229,138.0156 229.2656,137.875 229.4375,137.6563 C229.5469,137.5 229.5781,137.3125 229.5781,136.8906 L229.5781,135.4688 C229.5781,135.0313 229.5625,134.9063 229.4688,134.75 C229.3125,134.4844 229.0313,134.3438 228.7344,134.3438 C228.4375,134.3438 228.2344,134.4375 228.0156,134.75 L227.8438,134.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="110" x="239.5" y="143.8467">ObjectWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="211.5" x2="351.5" y1="155" y2="155"/><line style="stroke:#181818;stroke-width:0.5;" x1="211.5" x2="351.5" y1="163" y2="163"/></g><!--class KeyedWeakReference--><g id="elem_KeyedWeakReference"><rect fill="#F1F1F1" height="48" id="KeyedWeakReference" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="192" x="180.5" y="255"/><ellipse cx="195.5" cy="271" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M197.8438,266.6719 C196.9063,266.2344 196.3125,266.0938 195.4375,266.0938 C192.8125,266.0938 190.8125,268.1719 190.8125,270.8906 L190.8125,272.0156 C190.8125,274.5938 192.9219,276.4844 195.8125,276.4844 C197.0313,276.4844 198.1875,276.1875 198.9375,275.6406 C199.5156,275.2344 199.8438,274.7813 199.8438,274.3906 C199.8438,273.9375 199.4531,273.5469 198.9844,273.5469 C198.7656,273.5469 198.5625,273.625 198.375,273.8125 C197.9219,274.2969 197.9219,274.2969 197.7344,274.3906 C197.3125,274.6563 196.625,274.7813 195.8594,274.7813 C193.8125,274.7813 192.5156,273.6875 192.5156,271.9844 L192.5156,270.8906 C192.5156,269.1094 193.7656,267.7969 195.5,267.7969 C196.0781,267.7969 196.6875,267.9531 197.1563,268.2031 C197.6406,268.4844 197.8125,268.7031 197.9063,269.1094 C197.9688,269.5156 198,269.6406 198.1406,269.7656 C198.2813,269.9063 198.5156,270.0156 198.7344,270.0156 C199,270.0156 199.2656,269.875 199.4375,269.6563 C199.5469,269.5 199.5781,269.3125 199.5781,268.8906 L199.5781,267.4688 C199.5781,267.0313 199.5625,266.9063 199.4688,266.75 C199.3125,266.4844 199.0313,266.3438 198.7344,266.3438 C198.4375,266.3438 198.2344,266.4375 198.0156,266.75 L197.8438,266.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="160" x="209.5" y="275.8467">KeyedWeakReference</text><line style="stroke:#181818;stroke-width:0.5;" x1="181.5" x2="371.5" y1="287" y2="287"/><line style="stroke:#181818;stroke-width:0.5;" x1="181.5" x2="371.5" y1="295" y2="295"/></g><!--class OnObjectRetainedListener--><g id="elem_OnObjectRetainedListener"><rect codeLine="5" fill="#F1F1F1" height="64.2969" id="OnObjectRetainedListener" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="219" x="390" y="115"/><ellipse cx="405" cy="131" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M405.9531,127.7813 L407.6719,127.7813 C408.0625,127.7813 408.25,127.75 408.375,127.6719 C408.6406,127.5156 408.7813,127.2344 408.7813,126.9375 C408.7813,126.6719 408.6719,126.4063 408.4375,126.2344 C408.2656,126.125 408.125,126.0938 407.6719,126.0938 L402.5313,126.0938 C402.0938,126.0938 401.9688,126.1094 401.8125,126.2031 C401.5625,126.3594 401.4063,126.6563 401.4063,126.9375 C401.4063,127.2188 401.5469,127.4688 401.7656,127.6406 C401.9219,127.75 402.1094,127.7813 402.5313,127.7813 L404.25,127.7813 L404.25,134.2969 L402.5313,134.2969 C402.0938,134.2969 401.9688,134.3125 401.8125,134.4219 C401.5625,134.5781 401.4063,134.8594 401.4063,135.1563 C401.4063,135.4063 401.5469,135.6719 401.7656,135.8281 C401.9219,135.9531 402.125,136 402.5313,136 L407.6719,136 C408.4219,136 408.7813,135.7188 408.7813,135.1563 C408.7813,134.875 408.6719,134.625 408.4375,134.4531 C408.2656,134.3281 408.125,134.2969 407.6719,134.2969 L405.9531,134.2969 L405.9531,127.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="187" x="419" y="135.8467">OnObjectRetainedListener</text><line style="stroke:#181818;stroke-width:0.5;" x1="391" x2="608" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="391" x2="608" y1="155" y2="155"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="142" x="396" y="171.9951">onObjectRetained()</text></g><!--class InternalLeakCanary--><g id="elem_InternalLeakCanary"><rect codeLine="9" fill="#F1F1F1" height="72.5625" id="InternalLeakCanary" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="174" x="415.5" y="243"/><ellipse cx="431.85" cy="263.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M435.6313,259.1016 C435.6313,258.6641 435.6156,258.5234 435.5219,258.3672 C435.3813,258.1328 435.1,257.9766 434.8031,257.9766 C434.4594,257.9766 434.3188,258.1172 434.1469,258.5391 C433.5531,258.1641 432.8031,257.9766 431.9281,257.9766 C429.8188,257.9766 428.2406,259.2734 428.2406,260.9922 C428.2406,261.9609 428.7719,262.8672 429.6313,263.3516 C430.1781,263.6641 430.725,263.8359 431.8344,264.0234 C432.9906,264.2266 433.2563,264.2891 433.6156,264.4766 C433.9906,264.6797 434.225,265.0234 434.225,265.3828 C434.225,266.1172 433.2406,266.6641 431.9906,266.6641 C430.8656,266.6641 429.7875,266.1797 429.6156,265.5703 C429.4906,265.1016 429.4906,265.1016 429.3656,264.9922 C429.2094,264.8359 428.9906,264.7422 428.7563,264.7422 C428.475,264.7422 428.225,264.8672 428.0531,265.0859 C427.9438,265.2578 427.8969,265.4453 427.8969,265.8672 L427.8969,266.9922 C427.8969,267.7578 428.1781,268.1172 428.7719,268.1172 C429.0375,268.1172 429.1625,268.0547 429.4438,267.7109 C430.2875,268.1484 431.1781,268.3672 432.1,268.3672 C434.4281,268.3672 435.9906,267.1797 435.9906,265.4141 C435.9906,264.5234 435.6781,263.8359 434.9906,263.2891 C434.4594,262.8672 433.8188,262.6172 432.3344,262.3516 C431.0688,262.1172 430.975,262.0859 430.6469,261.9141 C430.2719,261.7266 430.0063,261.3359 430.0063,260.9766 C430.0063,260.2422 430.8656,259.6797 431.9281,259.6797 C432.9906,259.6797 433.8031,260.1484 433.9594,260.8203 C434.0688,261.3672 434.0688,261.3672 434.1938,261.5078 C434.3344,261.6328 434.5688,261.7422 434.8031,261.7422 C435.0688,261.7422 435.3188,261.6016 435.4906,261.3828 C435.6,261.2109 435.6313,261.0703 435.6313,260.6016 L435.6313,259.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="480.15" y="259.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="139" x="446.15" y="274.9639">InternalLeakCanary</text><line style="stroke:#181818;stroke-width:0.5;" x1="416.5" x2="588.5" y1="283.2656" y2="283.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="416.5" x2="588.5" y1="291.2656" y2="291.2656"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="162" x="421.5" y="308.2607">void sendEvent(Event)</text></g><!--class HeapDumpTrigger--><g id="elem_HeapDumpTrigger"><rect fill="#F1F1F1" height="48" id="HeapDumpTrigger" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="164" x="329.5" y="387"/><ellipse cx="344.5" cy="403" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M346.8438,398.6719 C345.9063,398.2344 345.3125,398.0938 344.4375,398.0938 C341.8125,398.0938 339.8125,400.1719 339.8125,402.8906 L339.8125,404.0156 C339.8125,406.5938 341.9219,408.4844 344.8125,408.4844 C346.0313,408.4844 347.1875,408.1875 347.9375,407.6406 C348.5156,407.2344 348.8438,406.7813 348.8438,406.3906 C348.8438,405.9375 348.4531,405.5469 347.9844,405.5469 C347.7656,405.5469 347.5625,405.625 347.375,405.8125 C346.9219,406.2969 346.9219,406.2969 346.7344,406.3906 C346.3125,406.6563 345.625,406.7813 344.8594,406.7813 C342.8125,406.7813 341.5156,405.6875 341.5156,403.9844 L341.5156,402.8906 C341.5156,401.1094 342.7656,399.7969 344.5,399.7969 C345.0781,399.7969 345.6875,399.9531 346.1563,400.2031 C346.6406,400.4844 346.8125,400.7031 346.9063,401.1094 C346.9688,401.5156 347,401.6406 347.1406,401.7656 C347.2813,401.9063 347.5156,402.0156 347.7344,402.0156 C348,402.0156 348.2656,401.875 348.4375,401.6563 C348.5469,401.5 348.5781,401.3125 348.5781,400.8906 L348.5781,399.4688 C348.5781,399.0313 348.5625,398.9063 348.4688,398.75 C348.3125,398.4844 348.0313,398.3438 347.7344,398.3438 C347.4375,398.3438 347.2344,398.4375 347.0156,398.75 L346.8438,398.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="132" x="358.5" y="407.8467">HeapDumpTrigger</text><line style="stroke:#181818;stroke-width:0.5;" x1="330.5" x2="492.5" y1="419" y2="419"/><line style="stroke:#181818;stroke-width:0.5;" x1="330.5" x2="492.5" y1="427" y2="427"/></g><!--class EventListener--><g id="elem_EventListener"><rect codeLine="14" fill="#F1F1F1" height="64.2969" id="EventListener" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="129" x="529" y="379"/><ellipse cx="544" cy="395" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M544.9531,391.7813 L546.6719,391.7813 C547.0625,391.7813 547.25,391.75 547.375,391.6719 C547.6406,391.5156 547.7813,391.2344 547.7813,390.9375 C547.7813,390.6719 547.6719,390.4063 547.4375,390.2344 C547.2656,390.125 547.125,390.0938 546.6719,390.0938 L541.5313,390.0938 C541.0938,390.0938 540.9688,390.1094 540.8125,390.2031 C540.5625,390.3594 540.4063,390.6563 540.4063,390.9375 C540.4063,391.2188 540.5469,391.4688 540.7656,391.6406 C540.9219,391.75 541.1094,391.7813 541.5313,391.7813 L543.25,391.7813 L543.25,398.2969 L541.5313,398.2969 C541.0938,398.2969 540.9688,398.3125 540.8125,398.4219 C540.5625,398.5781 540.4063,398.8594 540.4063,399.1563 C540.4063,399.4063 540.5469,399.6719 540.7656,399.8281 C540.9219,399.9531 541.125,400 541.5313,400 L546.6719,400 C547.4219,400 547.7813,399.7188 547.7813,399.1563 C547.7813,398.875 547.6719,398.625 547.4375,398.4531 C547.2656,398.3281 547.125,398.2969 546.6719,398.2969 L544.9531,398.2969 L544.9531,391.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="97" x="558" y="399.8467">EventListener</text><line style="stroke:#181818;stroke-width:0.5;" x1="530" x2="657" y1="411" y2="411"/><line style="stroke:#181818;stroke-width:0.5;" x1="530" x2="657" y1="419" y2="419"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="70" x="535" y="435.9951">onEvent()</text></g><!--class BackgroundThreadHeapAnalyzer--><g id="elem_BackgroundThreadHeapAnalyzer"><rect codeLine="17" fill="#F1F1F1" height="56.2656" id="BackgroundThreadHeapAnalyzer" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="266" x="201.5" y="503"/><ellipse cx="216.5" cy="523.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M220.2813,519.1016 C220.2813,518.6641 220.2656,518.5234 220.1719,518.3672 C220.0313,518.1328 219.75,517.9766 219.4531,517.9766 C219.1094,517.9766 218.9688,518.1172 218.7969,518.5391 C218.2031,518.1641 217.4531,517.9766 216.5781,517.9766 C214.4688,517.9766 212.8906,519.2734 212.8906,520.9922 C212.8906,521.9609 213.4219,522.8672 214.2813,523.3516 C214.8281,523.6641 215.375,523.8359 216.4844,524.0234 C217.6406,524.2266 217.9063,524.2891 218.2656,524.4766 C218.6406,524.6797 218.875,525.0234 218.875,525.3828 C218.875,526.1172 217.8906,526.6641 216.6406,526.6641 C215.5156,526.6641 214.4375,526.1797 214.2656,525.5703 C214.1406,525.1016 214.1406,525.1016 214.0156,524.9922 C213.8594,524.8359 213.6406,524.7422 213.4063,524.7422 C213.125,524.7422 212.875,524.8672 212.7031,525.0859 C212.5938,525.2578 212.5469,525.4453 212.5469,525.8672 L212.5469,526.9922 C212.5469,527.7578 212.8281,528.1172 213.4219,528.1172 C213.6875,528.1172 213.8125,528.0547 214.0938,527.7109 C214.9375,528.1484 215.8281,528.3672 216.75,528.3672 C219.0781,528.3672 220.6406,527.1797 220.6406,525.4141 C220.6406,524.5234 220.3281,523.8359 219.6406,523.2891 C219.1094,522.8672 218.4688,522.6172 216.9844,522.3516 C215.7188,522.1172 215.625,522.0859 215.2969,521.9141 C214.9219,521.7266 214.6563,521.3359 214.6563,520.9766 C214.6563,520.2422 215.5156,519.6797 216.5781,519.6797 C217.6406,519.6797 218.4531,520.1484 218.6094,520.8203 C218.7188,521.3672 218.7188,521.3672 218.8438,521.5078 C218.9844,521.6328 219.2188,521.7422 219.4531,521.7422 C219.7188,521.7422 219.9688,521.6016 220.1406,521.3828 C220.25,521.2109 220.2813,521.0703 220.2813,520.6016 L220.2813,519.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="312" y="519.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="234" x="230.5" y="534.9639">BackgroundThreadHeapAnalyzer</text><line style="stroke:#181818;stroke-width:0.5;" x1="202.5" x2="466.5" y1="543.2656" y2="543.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="202.5" x2="466.5" y1="551.2656" y2="551.2656"/></g><!--class LogcatEventListener--><g id="elem_LogcatEventListener"><rect codeLine="18" fill="#F1F1F1" height="56.2656" id="LogcatEventListener" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="182" x="502.5" y="503"/><ellipse cx="517.5" cy="523.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M521.2813,519.1016 C521.2813,518.6641 521.2656,518.5234 521.1719,518.3672 C521.0313,518.1328 520.75,517.9766 520.4531,517.9766 C520.1094,517.9766 519.9688,518.1172 519.7969,518.5391 C519.2031,518.1641 518.4531,517.9766 517.5781,517.9766 C515.4688,517.9766 513.8906,519.2734 513.8906,520.9922 C513.8906,521.9609 514.4219,522.8672 515.2813,523.3516 C515.8281,523.6641 516.375,523.8359 517.4844,524.0234 C518.6406,524.2266 518.9063,524.2891 519.2656,524.4766 C519.6406,524.6797 519.875,525.0234 519.875,525.3828 C519.875,526.1172 518.8906,526.6641 517.6406,526.6641 C516.5156,526.6641 515.4375,526.1797 515.2656,525.5703 C515.1406,525.1016 515.1406,525.1016 515.0156,524.9922 C514.8594,524.8359 514.6406,524.7422 514.4063,524.7422 C514.125,524.7422 513.875,524.8672 513.7031,525.0859 C513.5938,525.2578 513.5469,525.4453 513.5469,525.8672 L513.5469,526.9922 C513.5469,527.7578 513.8281,528.1172 514.4219,528.1172 C514.6875,528.1172 514.8125,528.0547 515.0938,527.7109 C515.9375,528.1484 516.8281,528.3672 517.75,528.3672 C520.0781,528.3672 521.6406,527.1797 521.6406,525.4141 C521.6406,524.5234 521.3281,523.8359 520.6406,523.2891 C520.1094,522.8672 519.4688,522.6172 517.9844,522.3516 C516.7188,522.1172 516.625,522.0859 516.2969,521.9141 C515.9219,521.7266 515.6563,521.3359 515.6563,520.9766 C515.6563,520.2422 516.5156,519.6797 517.5781,519.6797 C518.6406,519.6797 519.4531,520.1484 519.6094,520.8203 C519.7188,521.3672 519.7188,521.3672 519.8438,521.5078 C519.9844,521.6328 520.2188,521.7422 520.4531,521.7422 C520.7188,521.7422 520.9688,521.6016 521.1406,521.3828 C521.25,521.2109 521.2813,521.0703 521.2813,520.6016 L521.2813,519.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="571" y="519.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="150" x="531.5" y="534.9639">LogcatEventListener</text><line style="stroke:#181818;stroke-width:0.5;" x1="503.5" x2="683.5" y1="543.2656" y2="543.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="503.5" x2="683.5" y1="551.2656" y2="551.2656"/></g><!--class ToastEventListener--><g id="elem_ToastEventListener"><rect codeLine="19" fill="#F1F1F1" height="56.2656" id="ToastEventListener" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="173" x="720" y="503"/><ellipse cx="735" cy="523.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M738.7813,519.1016 C738.7813,518.6641 738.7656,518.5234 738.6719,518.3672 C738.5313,518.1328 738.25,517.9766 737.9531,517.9766 C737.6094,517.9766 737.4688,518.1172 737.2969,518.5391 C736.7031,518.1641 735.9531,517.9766 735.0781,517.9766 C732.9688,517.9766 731.3906,519.2734 731.3906,520.9922 C731.3906,521.9609 731.9219,522.8672 732.7813,523.3516 C733.3281,523.6641 733.875,523.8359 734.9844,524.0234 C736.1406,524.2266 736.4063,524.2891 736.7656,524.4766 C737.1406,524.6797 737.375,525.0234 737.375,525.3828 C737.375,526.1172 736.3906,526.6641 735.1406,526.6641 C734.0156,526.6641 732.9375,526.1797 732.7656,525.5703 C732.6406,525.1016 732.6406,525.1016 732.5156,524.9922 C732.3594,524.8359 732.1406,524.7422 731.9063,524.7422 C731.625,524.7422 731.375,524.8672 731.2031,525.0859 C731.0938,525.2578 731.0469,525.4453 731.0469,525.8672 L731.0469,526.9922 C731.0469,527.7578 731.3281,528.1172 731.9219,528.1172 C732.1875,528.1172 732.3125,528.0547 732.5938,527.7109 C733.4375,528.1484 734.3281,528.3672 735.25,528.3672 C737.5781,528.3672 739.1406,527.1797 739.1406,525.4141 C739.1406,524.5234 738.8281,523.8359 738.1406,523.2891 C737.6094,522.8672 736.9688,522.6172 735.4844,522.3516 C734.2188,522.1172 734.125,522.0859 733.7969,521.9141 C733.4219,521.7266 733.1563,521.3359 733.1563,520.9766 C733.1563,520.2422 734.0156,519.6797 735.0781,519.6797 C736.1406,519.6797 736.9531,520.1484 737.1094,520.8203 C737.2188,521.3672 737.2188,521.3672 737.3438,521.5078 C737.4844,521.6328 737.7188,521.7422 737.9531,521.7422 C738.2188,521.7422 738.4688,521.6016 738.6406,521.3828 C738.75,521.2109 738.7813,521.0703 738.7813,520.6016 L738.7813,519.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="784" y="519.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="141" x="749" y="534.9639">ToastEventListener</text><line style="stroke:#181818;stroke-width:0.5;" x1="721" x2="892" y1="543.2656" y2="543.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="721" x2="892" y1="551.2656" y2="551.2656"/></g><!--class AndroidDebugHeapAnalyzer--><g id="elem_AndroidDebugHeapAnalyzer"><rect codeLine="25" fill="#F1F1F1" height="56.2656" id="AndroidDebugHeapAnalyzer" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="234" x="217.5" y="619"/><ellipse cx="232.5" cy="639.1328" fill="#FF7700" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M236.2813,635.1016 C236.2813,634.6641 236.2656,634.5234 236.1719,634.3672 C236.0313,634.1328 235.75,633.9766 235.4531,633.9766 C235.1094,633.9766 234.9688,634.1172 234.7969,634.5391 C234.2031,634.1641 233.4531,633.9766 232.5781,633.9766 C230.4688,633.9766 228.8906,635.2734 228.8906,636.9922 C228.8906,637.9609 229.4219,638.8672 230.2813,639.3516 C230.8281,639.6641 231.375,639.8359 232.4844,640.0234 C233.6406,640.2266 233.9063,640.2891 234.2656,640.4766 C234.6406,640.6797 234.875,641.0234 234.875,641.3828 C234.875,642.1172 233.8906,642.6641 232.6406,642.6641 C231.5156,642.6641 230.4375,642.1797 230.2656,641.5703 C230.1406,641.1016 230.1406,641.1016 230.0156,640.9922 C229.8594,640.8359 229.6406,640.7422 229.4063,640.7422 C229.125,640.7422 228.875,640.8672 228.7031,641.0859 C228.5938,641.2578 228.5469,641.4453 228.5469,641.8672 L228.5469,642.9922 C228.5469,643.7578 228.8281,644.1172 229.4219,644.1172 C229.6875,644.1172 229.8125,644.0547 230.0938,643.7109 C230.9375,644.1484 231.8281,644.3672 232.75,644.3672 C235.0781,644.3672 236.6406,643.1797 236.6406,641.4141 C236.6406,640.5234 236.3281,639.8359 235.6406,639.2891 C235.1094,638.8672 234.4688,638.6172 232.9844,638.3516 C231.7188,638.1172 231.625,638.0859 231.2969,637.9141 C230.9219,637.7266 230.6563,637.3359 230.6563,636.9766 C230.6563,636.2422 231.5156,635.6797 232.5781,635.6797 C233.6406,635.6797 234.4531,636.1484 234.6094,636.8203 C234.7188,637.3672 234.7188,637.3672 234.8438,637.5078 C234.9844,637.6328 235.2188,637.7422 235.4531,637.7422 C235.7188,637.7422 235.9688,637.6016 236.1406,637.3828 C236.25,637.2109 236.2813,637.0703 236.2813,636.6016 L236.2813,635.1016 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="71" x="312" y="635.1387">&#171;Singleton&#187;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="202" x="246.5" y="650.9639">AndroidDebugHeapAnalyzer</text><line style="stroke:#181818;stroke-width:0.5;" x1="218.5" x2="450.5" y1="659.2656" y2="659.2656"/><line style="stroke:#181818;stroke-width:0.5;" x1="218.5" x2="450.5" y1="667.2656" y2="667.2656"/></g><!--reverse link ActivityWatcher to ReachabilityWatcher--><g id="link_ActivityWatcher_ReachabilityWatcher"><path codeLine="2" d="M168.109,31 C179.865,31 179.62,31 191.375,31 " fill="none" id="ActivityWatcher-backto-ReachabilityWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="156.109,31,162.109,35,168.109,31,162.109,27,156.109,31" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ReachabilityWatcher to ObjectWatcher--><g id="link_ReachabilityWatcher_ObjectWatcher"><path codeLine="3" d="M281.5,73.07 C281.5,92.848 281.5,103.196 281.5,122.965 " fill="none" id="ReachabilityWatcher-backto-ObjectWatcher" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="281.5,55.07,275.5,73.07,287.5,73.07,281.5,55.07" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ObjectWatcher to KeyedWeakReference--><g id="link_ObjectWatcher_KeyedWeakReference"><path codeLine="4" d="M280.1449,183.2321 C279.2349,206.8951 278.293,231.37 277.386,254.96 " fill="none" id="ObjectWatcher-backto-KeyedWeakReference" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="280.606,171.241,276.3784,177.0829,280.1449,183.2321,284.3725,177.3903,280.606,171.241" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="271.4131" y="191.0609">1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="268.588" y="243.9618">n</text></g><!--reverse link ObjectWatcher to OnObjectRetainedListener--><g id="link_ObjectWatcher_OnObjectRetainedListener"><path codeLine="8" d="M364.605,147 C377.038,147 377.47,147 389.903,147 " fill="none" id="ObjectWatcher-backto-OnObjectRetainedListener" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="352.605,147,358.605,151,364.605,147,358.605,143,352.605,147" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="360.3502" y="143.3003">1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="373.9157" y="143.5338">n</text></g><!--reverse link OnObjectRetainedListener to InternalLeakCanary--><g id="link_OnObjectRetainedListener_InternalLeakCanary"><path codeLine="12" d="M500.6337,197.1332 C501.0457,215.0112 501.153,219.635 501.594,238.724 " fill="none" id="OnObjectRetainedListener-backto-InternalLeakCanary" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="500.219,179.138,494.6353,197.2715,506.6321,196.995,500.219,179.138" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link InternalLeakCanary to HeapDumpTrigger--><g id="link_InternalLeakCanary_HeapDumpTrigger"><path codeLine="13" d="M468.3156,328.8349 C452.8196,350.9729 440.833,368.096 427.671,386.899 " fill="none" id="InternalLeakCanary-backto-HeapDumpTrigger" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="475.197,319.004,468.4793,321.6257,468.3156,328.8349,475.0333,326.2132,475.197,319.004" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link EventListener to LogcatEventListener--><g id="link_EventListener_LogcatEventListener"><path codeLine="20" d="M593.5,461.003 C593.5,479.576 593.5,484.968 593.5,502.817 " fill="none" id="EventListener-backto-LogcatEventListener" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="593.5,443.003,587.5,461.003,599.5,461.003,593.5,443.003" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link EventListener to ToastEventListener--><g id="link_EventListener_ToastEventListener"><path codeLine="21" d="M665.2083,451.7257 C698.7343,470.2987 725.214,484.968 757.433,502.817 " fill="none" id="EventListener-backto-ToastEventListener" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="649.463,443.003,662.3007,456.9741,668.1159,446.4773,649.463,443.003" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link EventListener to BackgroundThreadHeapAnalyzer--><g id="link_EventListener_BackgroundThreadHeapAnalyzer"><path codeLine="23" d="M512.431,448.935 C471.078,467.776 434.224,484.566 393.935,502.921 " fill="none" id="EventListener-backto-BackgroundThreadHeapAnalyzer" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="528.811,441.472,509.9434,443.475,514.9187,454.395,528.811,441.472" style="stroke:#181818;stroke-width:1.0;"/></g><!--link InternalLeakCanary to EventListener--><g id="link_InternalLeakCanary_EventListener"><path codeLine="24" d="M590.5,303 C621.07,303 615.2788,341.423 606.0268,373.006 " fill="none" id="InternalLeakCanary-to-EventListener" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="604.34,378.764,610.7088,371.2515,605.7456,373.9656,603.0315,369.0025,604.34,378.764" style="stroke:#181818;stroke-width:1.0;"/></g><!--link BackgroundThreadHeapAnalyzer to AndroidDebugHeapAnalyzer--><g id="link_BackgroundThreadHeapAnalyzer_AndroidDebugHeapAnalyzer"><path codeLine="26" d="M334.5,559.016 C334.5,577.0572 334.5,594.7002 334.5,612.7824 " fill="none" id="BackgroundThreadHeapAnalyzer-to-AndroidDebugHeapAnalyzer" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="334.5,618.7824,338.5,609.7824,334.5,613.7824,330.5,609.7824,334.5,618.7824" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[bP91Jm8n48Nl_HMJzI0Qb-29X10I58b64X8WuJoqmr9PMz8jc4NzxxOBGe0kQ0zDkZlpljStbSgIcI8d613o6KvaAcq-HijdP5YRMxdQd-4s3fO5la7pgrg5_kIDkFqjEpX1T1yvlHWY5S4hvIJ6XFC1JScGuiJapbXVRHe7P54g4ZsPML9EuPE1M_heT-M6VGTH1QbCZF4KimnUF5LXsdDU7b6XoQ7PXChmxghRhTThjHiOIfMaPBM2LclhOAMbW8oKU5gHifLYBqoK6I-oEKMn0Dqdz4ouw2pV5oCZayHPtKTJe4xosDZm3ZQNUa0-JunUAZ6Q6KBXzTeEaw-zb_BhRTjxEk5e3r6NkqOQityq7LNwW0BSKDafY5r3I0xNULUR3pJ2WI_AdWijCAX6O_S088vRXmQsaRILCEwfT6YoJFuyWxF3ywGorHy0]--></g></svg>

<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">ActivityWatcher</span>(</span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">val</span> application: Application,</span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">val</span> reachabilityWatcher: ReachabilityWatcher <span class="comment">//ObjectWatcher实例</span></span><br><span class="line">) : InstallableWatcher &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">val</span> lifecycleCallbacks = <span class="comment">//activity生命周期监听事件回调</span></span><br><span class="line">    <span class="keyword">object</span> : Application.ActivityLifecycleCallbacks <span class="keyword">by</span> noOpDelegate() &#123;</span><br><span class="line">      <span class="comment">//当Activity被销毁时会收到onActivityDestroyed事件通知，其中activity参数就是被销毁的activity实例</span></span><br><span class="line">      <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onActivityDestroyed</span><span class="params">(activity: <span class="type">Activity</span>)</span></span> &#123;</span><br><span class="line">        reachabilityWatcher.expectWeaklyReachable(</span><br><span class="line">          activity, <span class="string">&quot;<span class="subst">$&#123;activity::class.java.name&#125;</span> received Activity#onDestroy() callback&quot;</span></span><br><span class="line">        )</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//初始化时调用，注册Activity生命周期回调监听</span></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">install</span><span class="params">()</span></span> &#123;</span><br><span class="line">    application.registerActivityLifecycleCallbacks(lifecycleCallbacks)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">uninstall</span><span class="params">()</span></span> &#123;</span><br><span class="line">    application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>ActivityWatcher的作用是注册Activity生命周期监听，在onActivityDestroyed时将activity实例通过<code>ObjectWatcher#expectWeaklyReachable</code>注册到监控表中。下面看下<code>ObjectWatcher#expectWeaklyReachable</code>的实现：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">val</span> watchedObjects = mutableMapOf&lt;String, KeyedWeakReference&gt;()</span><br><span class="line"></span><br><span class="line"><span class="meta">@Synchronized</span> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">expectWeaklyReachable</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  watchedObject: <span class="type">Any</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">  description: <span class="type">String</span></span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (!isEnabled()) &#123;</span><br><span class="line">    <span class="keyword">return</span></span><br><span class="line">  &#125;</span><br><span class="line">  removeWeaklyReachableObjects()</span><br><span class="line">  <span class="keyword">val</span> key = UUID.randomUUID().toString()</span><br><span class="line">  <span class="keyword">val</span> watchUptimeMillis = clock.uptimeMillis()</span><br><span class="line">  <span class="comment">//KeyedWeakReference是弱引用，是WeakReference的子类</span></span><br><span class="line">  <span class="keyword">val</span> reference = KeyedWeakReference(watchedObject, key, description, watchUptimeMillis, queue)</span><br><span class="line">  ......</span><br><span class="line">  watchedObjects[key] = reference  <span class="comment">//存入监控表中</span></span><br><span class="line">  checkRetainedExecutor.execute &#123;</span><br><span class="line">    moveToRetained(key) <span class="comment">//弱引用标记为retained状态（既没有被回收）</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过一个弱引用KeyedWeakReference来持有activity，然后注册到监控表中。KeyedWeakReference构造函数指定了<code>ReferenceQueue</code>，因此当实例被回收后，弱引用就会被添加到<code>ReferenceQueue</code>中。</p>
<p>最后通过checkRetainedExecutor来执行一个Runnable任务，checkRetainedExecutor在ObjectWatcher的构造函数中传入，定义如下：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> objectWatcher = ObjectWatcher(</span><br><span class="line">  clock = &#123; SystemClock.uptimeMillis() &#125;,</span><br><span class="line">  checkRetainedExecutor = &#123;</span><br><span class="line">    check(isInstalled) &#123;</span><br><span class="line">      <span class="string">&quot;AppWatcher not installed&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//在主线程执行一个延时任务，retainedDelayMillis默认值是5秒</span></span><br><span class="line">    mainHandler.postDelayed(it, retainedDelayMillis)</span><br><span class="line">  &#125;,</span><br><span class="line">  isEnabled = &#123; <span class="literal">true</span> &#125;</span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<p>总结一下上面的代码流程：当activity被销毁后，会创建一个弱引用KeyedWeakReference来持有这个activity实例，KeyedWeakReference还包含了一个uuid和activity的描述信息，而且弱引用关联了ReferenceQueue，在对象实例被回收后，弱引用本身会被添加到ReferenceQueue中。然后启动一个延时5秒（可配置）的任务来检查这个弱引用持有的实例是否被回收。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引用队列，当弱引用持有的实例被回收后，弱引用本身会被添加到队列中</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">val</span> queue = ReferenceQueue&lt;Any&gt;()</span><br><span class="line"></span><br><span class="line"><span class="meta">@Synchronized</span> <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">moveToRetained</span><span class="params">(key: <span class="type">String</span>)</span></span> &#123;</span><br><span class="line">  removeWeaklyReachableObjects() <span class="comment">//清理已经被GC回收的对象弱引用</span></span><br><span class="line">  <span class="keyword">val</span> retainedRef = watchedObjects[key]</span><br><span class="line">  <span class="keyword">if</span> (retainedRef != <span class="literal">null</span>) &#123; <span class="comment">//不为空表示key对应的监控对象（activity）没有被回收，可能存在内存泄漏</span></span><br><span class="line">    retainedRef.retainedUptimeMillis = clock.uptimeMillis() <span class="comment">//更新retained时间</span></span><br><span class="line">    <span class="comment">//onObjectRetainedListeners是一个监听者列表，InternalLeakCanary就是其中之一，默认也是唯一的一个</span></span><br><span class="line">    onObjectRetainedListeners.forEach &#123; it.onObjectRetained() &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">removeWeaklyReachableObjects</span><span class="params">()</span></span> &#123;</span><br><span class="line">  <span class="comment">// WeakReferences are enqueued as soon as the object to which they point to becomes weakly</span></span><br><span class="line">  <span class="comment">// reachable. This is before finalization or garbage collection has actually happened.</span></span><br><span class="line">  <span class="keyword">var</span> ref: KeyedWeakReference?</span><br><span class="line">  <span class="keyword">do</span> &#123;</span><br><span class="line">    ref = queue.poll() <span class="keyword">as</span> KeyedWeakReference?</span><br><span class="line">    <span class="keyword">if</span> (ref != <span class="literal">null</span>) &#123;</span><br><span class="line">      <span class="comment">//从引用队列中拿到的对象就表示这个实例已经被GC正常回收了，所以从监控表中删除引用</span></span><br><span class="line">      watchedObjects.remove(ref.key)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125; <span class="keyword">while</span> (ref != <span class="literal">null</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>当检测到对象没有被回收后，会调用<code>leakcanary.internal.InternalLeakCanary#onObjectRetained</code>来触发泄漏检测：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//InternalLeakCanary.kt</span></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onObjectRetained</span><span class="params">()</span></span> = scheduleRetainedObjectCheck()</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">fun</span> <span class="title">scheduleRetainedObjectCheck</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span>::heapDumpTrigger.isInitialized) &#123;</span><br><span class="line">      heapDumpTrigger.scheduleRetainedObjectCheck()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//HeapDumpTrigger.kt</span></span><br><span class="line">  <span class="function"><span class="keyword">fun</span> <span class="title">scheduleRetainedObjectCheck</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">    delayMillis: <span class="type">Long</span> = <span class="number">0</span>L  <span class="comment">//默认延时是0，调用时没有传参，所以使用默认值0</span></span></span></span><br><span class="line"><span class="params"><span class="function">  )</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> checkCurrentlyScheduledAt = checkScheduledAt</span><br><span class="line">    <span class="keyword">if</span> (checkCurrentlyScheduledAt &gt; <span class="number">0</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    checkScheduledAt = SystemClock.uptimeMillis() + delayMillis</span><br><span class="line">    backgroundHandler.postDelayed(&#123;  <span class="comment">//启动后台任务</span></span><br><span class="line">      checkScheduledAt = <span class="number">0</span></span><br><span class="line">      checkRetainedObjects()</span><br><span class="line">    &#125;, delayMillis)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//检测内存泄漏</span></span><br><span class="line">  <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">checkRetainedObjects</span><span class="params">()</span></span> &#123;</span><br><span class="line">    ......<span class="comment">//忽略部分代码</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取泄漏对象个数</span></span><br><span class="line">    <span class="keyword">var</span> retainedReferenceCount = objectWatcher.retainedObjectCount</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (retainedReferenceCount &gt; <span class="number">0</span>) &#123;</span><br><span class="line">      gcTrigger.runGc() <span class="comment">//执行Runtime.getRuntime().gc()</span></span><br><span class="line">      retainedReferenceCount = objectWatcher.retainedObjectCount</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//检查对象泄漏个数，如果小于阈值（默认是5）直接返回不执行后续步骤</span></span><br><span class="line">    <span class="keyword">if</span> (checkRetainedCount(retainedReferenceCount, config.retainedVisibleThreshold)) <span class="keyword">return</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">val</span> now = SystemClock.uptimeMillis()</span><br><span class="line">    <span class="keyword">val</span> elapsedSinceLastDumpMillis = now - lastHeapDumpUptimeMillis</span><br><span class="line">    <span class="comment">//如果距离上次分析堆栈信息不足1分钟则返回</span></span><br><span class="line">    <span class="keyword">if</span> (elapsedSinceLastDumpMillis &lt; WAIT_BETWEEN_HEAP_DUMPS_MILLIS) &#123;</span><br><span class="line">      onRetainInstanceListener.onEvent(DumpHappenedRecently)</span><br><span class="line">      showRetainedCountNotification(</span><br><span class="line">        objectCount = retainedReferenceCount,</span><br><span class="line">        contentText = application.getString(R.string.leak_canary_notification_retained_dump_wait)</span><br><span class="line">      )</span><br><span class="line">      scheduleRetainedObjectCheck(</span><br><span class="line">        delayMillis = WAIT_BETWEEN_HEAP_DUMPS_MILLIS - elapsedSinceLastDumpMillis</span><br><span class="line">      )</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    dismissRetainedCountNotification()</span><br><span class="line">    <span class="keyword">val</span> visibility = <span class="keyword">if</span> (applicationVisible) <span class="string">&quot;visible&quot;</span> <span class="keyword">else</span> <span class="string">&quot;not visible&quot;</span></span><br><span class="line">    dumpHeap( <span class="comment">//保存堆栈信息</span></span><br><span class="line">      retainedReferenceCount = retainedReferenceCount,</span><br><span class="line">      retry = <span class="literal">true</span>,</span><br><span class="line">      reason = <span class="string">&quot;<span class="variable">$retainedReferenceCount</span> retained objects, app is <span class="variable">$visibility</span>&quot;</span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1556px" preserveAspectRatio="none" style="width:1034px;height:1556px;background:#FFFFFF;" version="1.1" viewBox="0 0 1034 1556" width="1034px" zoomAndPan="magnify"><defs/><g><rect fill="none" height="20.9531" style="stroke:none;stroke-width:1.0;" width="1001" x="15" y="12.7451"/><ellipse cx="115" cy="48.6982" fill="#222222" rx="10" ry="10" style="stroke:#222222;stroke-width:1.0;"/><polygon fill="#F1F1F1" points="30,78.6982,200,78.6982,210,95.6826,200,112.667,30,112.667" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="146" x="40" y="99.8369">onActivityDestroyed&#20107;&#20214;</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="134" x="48" y="132.667"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="114" x="58" y="153.8057">&#29983;&#25104;activity&#25551;&#36848;&#20449;&#24687;</text><line style="stroke:#000000;stroke-width:1.5;" x1="15" x2="15" y1="12.7451" y2="1544.4946"/><rect fill="#F1F1F1" height="75.875" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="200" x="280" y="203.895"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="180" x="290" y="225.0337">&#28165;&#29702;&#24341;&#29992;&#34920;&#20013;&#24050;&#32463;&#34987;&#22238;&#25910;&#30340;&#23545;&#35937;&#65306;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="174" x="290" y="239.0024">&#24490;&#29615;&#20174;ReferenceQueue&#20013;&#21462;&#20986;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="168" x="290" y="252.9712">&#24050;&#32463;&#34987;&#22238;&#25910;&#30340;&#24341;&#29992;&#65292;&#24182;&#20174;&#24341;&#29992;&#34920;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="36" x="290" y="266.9399">&#20013;&#21024;&#38500;</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="209" x="275.5" y="299.77"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="189" x="285.5" y="320.9087">&#36890;&#36807;UUID.randomUUID()&#29983;&#25104;key</text><rect fill="#F1F1F1" height="89.8438" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="227" x="266.5" y="353.7388"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="207" x="276.5" y="374.8774">&#26500;&#24314;&#24369;&#24341;&#29992;KeyedWeakReference&#65292;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="198" x="276.5" y="388.8462">&#24182;&#20851;&#32852;ReferenceQueue&#65292;&#24369;&#24341;&#29992;&#25345;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="190" x="276.5" y="402.8149">&#26377;&#30417;&#25511;&#23545;&#35937;&#12289;key&#12289;&#25551;&#36848;&#20449;&#24687;&#12289;&#30417;&#25511;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="192" x="276.5" y="416.7837">&#26102;&#38388;&#12290;&#24403;&#30417;&#25511;&#23545;&#35937;&#34987;&#22238;&#25910;&#21518;&#65292;&#24369;&#24341;&#29992;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="162" x="276.5" y="430.7524">&#20250;&#34987;&#28155;&#21152;&#21040;ReferenceQueue</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="228" x="266" y="463.5825"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="160" x="276" y="484.7212">&#24369;&#24341;&#29992;&#28155;&#21152;&#21040;&#24341;&#29992;&#34920;(map)&#20013;:</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="208" x="276" y="498.6899">watchedObjects[key] = reference</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="212" x="274" y="565.7236"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="192" x="284" y="586.8623">&#20877;&#27425;&#28165;&#29702;&#24341;&#29992;&#34920;&#20013;&#24050;&#32463;&#34987;&#22238;&#25910;&#30340;&#23545;&#35937;</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="160" x="300" y="619.6924"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="136" x="310" y="640.8311">&#20174;&#24341;&#29992;&#34920;&#20013;&#21462;&#20986;&#30417;&#25511;&#23545;&#35937;:</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="130" x="310" y="654.7998">watchedObjects[key]</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="142" x="309" y="748.8369"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="319" y="769.9756">&#26356;&#26032;&#27844;&#28431;&#26816;&#27979;&#26102;&#38388;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="122" x="319" y="783.9443">retainedUptimeMillis</text><polygon fill="#F1F1F1" points="352.5,687.6299,407.5,687.6299,419.5,699.6299,407.5,711.6299,352.5,711.6299,340.5,699.6299,352.5,687.6299" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="384" y="721.8403">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="77" x="384" y="734.645">&#24341;&#29992;&#34920;&#20013;&#36824;&#23384;&#22312;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="44" x="384" y="747.4497">&#34920;&#31034;&#27844;&#28431;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="55" x="352.5" y="703.438">&#26159;&#21542;&#27844;&#28431;&#65311;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="419.5" y="697.0356">no</text><ellipse cx="455.5" cy="699.6299" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="455.5" cy="699.6299" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="188" x="286" y="941.9712"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="168" x="296" y="963.1099">&#28165;&#29702;&#24341;&#29992;&#34920;&#20013;&#24050;&#32463;&#34987;&#22238;&#25910;&#30340;&#23545;&#35937;</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="298" x="231" y="995.9399"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="278" x="241" y="1017.0786">&#33719;&#21462;&#27844;&#28431;&#23545;&#35937;&#25968;&#37327;&#65306;&#24341;&#29992;&#34920;&#20013;retainedUptimeMillis</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="108" x="241" y="1031.0474">&#24050;&#34987;&#26356;&#26032;&#30340;&#24341;&#29992;&#25968;&#37327;</text><line style="stroke:#000000;stroke-width:1.5;" x1="225" x2="225" y1="12.7451" y2="1544.4946"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="137" x="561.5" y="816.7744"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="117" x="571.5" y="837.9131">onObjectRetained()</text><line style="stroke:#000000;stroke-width:1.5;" x1="533" x2="533" y1="12.7451" y2="1544.4946"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="237" x="739.5" y="888.0024"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="217" x="749.5" y="909.1411">&#21518;&#21488;&#32447;&#31243;&#25191;&#34892;checkRetainedObjects()</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="175" x="770.5" y="1112.2798"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="155" x="780.5" y="1133.4185">Runtime.getRuntime().gc()</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="140" x="788" y="1181.2485"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="120" x="798" y="1202.3872">&#37325;&#26032;&#33719;&#21462;&#27844;&#28431;&#23545;&#35937;&#25968;&#37327;</text><polygon fill="#F1F1F1" points="805,1063.8774,911,1063.8774,923,1075.8774,911,1087.8774,805,1087.8774,793,1075.8774,805,1063.8774" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="862" y="1098.0879">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="106" x="805" y="1079.6855">&#27844;&#28431;&#23545;&#35937;&#25968;&#37327;&#22823;&#20110;0&#65311;</text><polygon fill="#F1F1F1" points="858,1235.2173,870,1247.2173,858,1259.2173,846,1247.2173,858,1235.2173" style="stroke:#181818;stroke-width:0.5;"/><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="254" x="731" y="1327.6196"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="234" x="741" y="1348.7583">Debug.dumpHprofData(heapDumpFile)</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="84" x="741" y="1362.7271">&#20445;&#23384;&#22534;&#26632;&#21040;&#25991;&#20214;</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="218" x="749" y="1410.5571"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="198" x="759" y="1431.6958">BackgroundThreadHeapAnalyzer</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="48" x="759" y="1445.6646">&#35299;&#26512;&#22534;&#26632;</text><polygon fill="#F1F1F1" points="779,1279.2173,937,1279.2173,949,1291.2173,937,1303.2173,779,1303.2173,767,1291.2173,779,1279.2173" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="70" x="862" y="1313.4277">dumpHeap()</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="158" x="779" y="1295.0254">&#27844;&#28431;&#23545;&#35937;&#25968;&#37327;&#22823;&#20110;&#38408;&#20540;(&#40664;&#35748;5)&#65311;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="949" y="1288.623">no</text><polygon fill="#F1F1F1" points="858,1478.4946,870,1490.4946,858,1502.4946,846,1490.4946,858,1478.4946" style="stroke:#181818;stroke-width:0.5;"/><ellipse cx="858" cy="1533.4946" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="858" cy="1533.4946" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><line style="stroke:#000000;stroke-width:1.5;" x1="725" x2="725" y1="12.7451" y2="1544.4946"/><line style="stroke:#000000;stroke-width:1.5;" x1="1014" x2="1014" y1="12.7451" y2="1544.4946"/><line style="stroke:#181818;stroke-width:1.0;" x1="115" x2="115" y1="58.6982" y2="78.6982"/><polygon fill="#181818" points="111,68.6982,115,78.6982,119,68.6982,115,72.6982" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="115" x2="115" y1="112.667" y2="132.667"/><polygon fill="#181818" points="111,122.667,115,132.667,119,122.667,115,126.667" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="279.77" y2="299.77"/><polygon fill="#181818" points="376,289.77,380,299.77,384,289.77,380,293.77" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="333.7388" y2="353.7388"/><polygon fill="#181818" points="376,343.7388,380,353.7388,384,343.7388,380,347.7388" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="443.5825" y2="463.5825"/><polygon fill="#181818" points="376,453.5825,380,463.5825,384,453.5825,380,457.5825" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="511.52" y2="565.7236"/><polygon fill="#181818" points="376,555.7236,380,565.7236,384,555.7236,380,559.7236" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="95" x="384" y="532.8247">&#20027;&#32447;&#31243;&#24310;&#26102;5&#31186;&#25191;&#34892;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="106" x="384" y="545.6294">moveToRetained()</text><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="599.6924" y2="619.6924"/><polygon fill="#181818" points="376,609.6924,380,619.6924,384,609.6924,380,613.6924" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="711.6299" y2="748.8369"/><polygon fill="#181818" points="376,738.8369,380,748.8369,384,738.8369,380,742.8369" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="419.5" x2="444.5" y1="699.6299" y2="699.6299"/><polygon fill="#181818" points="434.5,695.6299,444.5,699.6299,434.5,703.6299,438.5,699.6299" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="796.7744" y2="801.7744"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="630" y1="801.7744" y2="801.7744"/><line style="stroke:#181818;stroke-width:1.0;" x1="630" x2="630" y1="801.7744" y2="816.7744"/><polygon fill="#181818" points="626,806.7744,630,816.7744,634,806.7744,630,810.7744" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="667.6299" y2="687.6299"/><polygon fill="#181818" points="376,677.6299,380,687.6299,384,677.6299,380,681.6299" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="975.9399" y2="995.9399"/><polygon fill="#181818" points="376,985.9399,380,995.9399,384,985.9399,380,989.9399" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1146.2485" y2="1181.2485"/><polygon fill="#181818" points="854,1171.2485,858,1181.2485,862,1171.2485,858,1175.2485" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1087.8774" y2="1112.2798"/><polygon fill="#181818" points="854,1102.2798,858,1112.2798,862,1102.2798,858,1106.2798" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="923" x2="955.5" y1="1075.8774" y2="1075.8774"/><polygon fill="#181818" points="951.5,1153.7485,955.5,1163.7485,959.5,1153.7485,955.5,1157.7485" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="955.5" x2="955.5" y1="1075.8774" y2="1247.2173"/><line style="stroke:#181818;stroke-width:1.0;" x1="955.5" x2="870" y1="1247.2173" y2="1247.2173"/><polygon fill="#181818" points="880,1243.2173,870,1247.2173,880,1251.2173,876,1247.2173" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1215.2173" y2="1235.2173"/><polygon fill="#181818" points="854,1225.2173,858,1235.2173,862,1225.2173,858,1229.2173" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1375.5571" y2="1410.5571"/><polygon fill="#181818" points="854,1400.5571,858,1410.5571,862,1400.5571,858,1404.5571" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1303.2173" y2="1327.6196"/><polygon fill="#181818" points="854,1317.6196,858,1327.6196,862,1317.6196,858,1321.6196" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="949" x2="995" y1="1291.2173" y2="1291.2173"/><polygon fill="#181818" points="991,1383.0571,995,1393.0571,999,1383.0571,995,1387.0571" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="995" x2="995" y1="1291.2173" y2="1490.4946"/><line style="stroke:#181818;stroke-width:1.0;" x1="995" x2="870" y1="1490.4946" y2="1490.4946"/><polygon fill="#181818" points="880,1486.4946,870,1490.4946,880,1494.4946,876,1490.4946" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1458.4946" y2="1478.4946"/><polygon fill="#181818" points="854,1468.4946,858,1478.4946,862,1468.4946,858,1472.4946" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1259.2173" y2="1279.2173"/><polygon fill="#181818" points="854,1269.2173,858,1279.2173,862,1269.2173,858,1273.2173" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1502.4946" y2="1522.4946"/><polygon fill="#181818" points="854,1512.4946,858,1522.4946,862,1512.4946,858,1516.4946" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="115" x2="115" y1="166.6357" y2="188.895"/><line style="stroke:#181818;stroke-width:1.0;" x1="115" x2="380" y1="188.895" y2="188.895"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="188.895" y2="203.895"/><polygon fill="#181818" points="376,193.895,380,203.895,384,193.895,380,197.895" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="172" x="119" y="182.395">&#35843;&#29992;expectWeaklyReachable()</text><line style="stroke:#181818;stroke-width:1.0;" x1="630" x2="630" y1="850.7432" y2="873.0024"/><line style="stroke:#181818;stroke-width:1.0;" x1="630" x2="858" y1="873.0024" y2="873.0024"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="873.0024" y2="888.0024"/><polygon fill="#181818" points="854,878.0024,858,888.0024,862,878.0024,858,882.0024" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="205" x="634" y="866.5024">&#35843;&#29992;scheduleRetainedObjectCheck()</text><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="921.9712" y2="926.9712"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="380" y1="926.9712" y2="926.9712"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="926.9712" y2="941.9712"/><polygon fill="#181818" points="376,931.9712,380,941.9712,384,931.9712,380,935.9712" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="380" y1="1043.8774" y2="1048.8774"/><line style="stroke:#181818;stroke-width:1.0;" x1="380" x2="858" y1="1048.8774" y2="1048.8774"/><line style="stroke:#181818;stroke-width:1.0;" x1="858" x2="858" y1="1048.8774" y2="1063.8774"/><polygon fill="#181818" points="854,1053.8774,858,1063.8774,862,1053.8774,858,1057.8774" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacing" textLength="149" x="45.5" y="29.4531">ActivityWatcher</text><text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacing" textLength="139" x="309.5" y="29.4531">ObjectWatcher</text><text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacing" textLength="182" x="538" y="29.4531">InternalLeakCanary</text><text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacing" textLength="171" x="784" y="29.4531">HeapDumpTrigger</text><!--SRC=[bLJFRn9R5DxFNp7BOM7pDcuWcgZ4QDGOcpOkv2rkXrCO2tV8pA0FmuA-Lmkr2gYr8jLQj956dw_uuz4MKFuOkNU6LVy5pvqBI6qrkfdCt7k-SxxlVETCzfJk63SC9tELE7eShAnYEyHobA19XpTXi1tBp42qrrhkjPlgIINehZpdXJ8P1F1IoUisUjqQdzyEATdBCzT1TqRvZfrKlSO_xieM_9KIvq3c4fb987gSp2H02uIK8D-zxPONMUSHHdcrhTxkMxRptcsNl1TlsDewNscwrGMslUUzg-rtgX7AFhzsYzkzTd4IPi42giELDAH1m4ghBD_2YCDmF_b-voxRQo9oL2j21QomqN-oYKJwkQhNpKzFdmzFM8H6pQHurG9IxXna1DVr1TPkiSuxcU82O6E4fX4Nh844zfhizWTlVkKWHL5_YEHtvoEKFrror-xpObtA-vARnohu76yfVieO37_Sx3_- -2NtD_lqS1mtKihAnV4QgAvJnKk-qsPtDbYXSP0Eolb6PnWoQesM9Aa0TYSOeJTzCwFIMViQSlnJFQ5QmsGXON9lj-sskkxMCcitaUTnj_w0BzMz6dOZQTw0ANCI769GYFgMiyLx_D_QhnkFa77RHbwFTo6e7iaqf1YpgiOhswpyYdzOu9tIVkTvG7NYG3Lg1XHLjHqpfK321Yq3DfetLiNhLjZR2dkAhSG3TxCbCmXKaAzzvAiDUS1VvlZ_ozAV2BK6KgTJZf64IqOYOTWX1MZKc5Movwa35YM9YpWrPmWbLYOhrarI7c_IQ7Di8IcTWE6b33qJ1trEn6NF0Kc5qydKb6N4OcBdWZW7hDIGVaWNT15zC87jWxzRr-1lUU8LTz07sG9vo1yr-ddiS7Kymr7zyBTKpARVnT6AIlnHedmN3rLYc_LUg_Z7DqlHGj-ToJGLnIPYu0nUjS14J1UQyRQVluTLVqH_wDNFIlOh1PRhQFrsnVjlytZW405qBuhqXOn1pJ3Cf6CJ_c7ACcV3n25QVA3oh9600AvhzvaOjur5lb70NUIhUVpZ-k3JH9-BMMQQHgVY5f2eo7iAfoXp2ooSpVfBlbwMk90_oge_srA6cE-l]--></g></svg>

<h2 id="Service泄漏监控"><a href="#Service泄漏监控" class="headerlink" title="Service泄漏监控"></a>Service泄漏监控</h2><p>Activity可以通过Application注册生命周期事件回调来监控Activity的销毁，但是Service没有这样的机制，需要采用hook系统AMS方式来监控Service的销毁。</p>
<p>Service的内存泄漏监控分为两个阶段：onServicePreDestroy和onServiceDestroyed。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">onServicePreDestroy</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  token: <span class="type">IBinder</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">  service: <span class="type">Service</span></span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span> &#123;</span><br><span class="line">  servicesToBeDestroyed[token] = WeakReference(service)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">onServiceDestroyed</span><span class="params">(token: <span class="type">IBinder</span>)</span></span> &#123;</span><br><span class="line">  servicesToBeDestroyed.remove(token)?.also &#123; serviceWeakReference -&gt;</span><br><span class="line">    serviceWeakReference.<span class="keyword">get</span>()?.let &#123; service -&gt;</span><br><span class="line">      reachabilityWatcher.expectWeaklyReachable(</span><br><span class="line">        service, <span class="string">&quot;<span class="subst">$&#123;service::class.java.name&#125;</span> received Service#onDestroy() callback&quot;</span></span><br><span class="line">      )</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>从代码中可以看出<code>onServicePreDestroy</code>的作用是把service对象通过弱引用保存到map中，然后在<code>onServiceDestroyed</code>中取出service对象，并触发泄漏检测逻辑。</p>
<h3 id="onServicePreDestroy获取service实例"><a href="#onServicePreDestroy获取service实例" class="headerlink" title="onServicePreDestroy获取service实例"></a>onServicePreDestroy获取service实例</h3><p>Service的创建、绑定、停止都会走到<code>ActivityThread.H</code>类，<code>ActivityThread</code>相关代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">class</span> <span class="title class_">ActivityThread</span> <span class="keyword">extends</span> <span class="title class_">ClientTransactionHandler</span></span><br><span class="line">        <span class="keyword">implements</span> <span class="title class_">ActivityThreadInternal</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="keyword">final</span> <span class="type">H</span> <span class="variable">mH</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">H</span>();</span><br><span class="line">    ......</span><br><span class="line">    <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">    <span class="keyword">final</span> ArrayMap&lt;IBinder, Service&gt; mServices = <span class="keyword">new</span> <span class="title class_">ArrayMap</span>&lt;&gt;();</span><br><span class="line">    ......</span><br><span class="line">    <span class="keyword">class</span> <span class="title class_">H</span> <span class="keyword">extends</span> <span class="title class_">Handler</span> &#123;</span><br><span class="line">        ......</span><br><span class="line">        <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">CREATE_SERVICE</span>          <span class="operator">=</span> <span class="number">114</span>; <span class="comment">//创建服务</span></span><br><span class="line">        <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">SERVICE_ARGS</span>            <span class="operator">=</span> <span class="number">115</span>; <span class="comment">//Service#onStartCommand</span></span><br><span class="line">        <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">STOP_SERVICE</span>            <span class="operator">=</span> <span class="number">116</span>; <span class="comment">//停止服务</span></span><br><span class="line">        ......</span><br><span class="line">        <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">BIND_SERVICE</span>            <span class="operator">=</span> <span class="number">121</span>; <span class="comment">//绑定服务</span></span><br><span class="line">        <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">UNBIND_SERVICE</span>          <span class="operator">=</span> <span class="number">122</span>; <span class="comment">//解绑</span></span><br><span class="line">        ......</span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleMessage</span><span class="params">(Message msg)</span> &#123;</span><br><span class="line">            <span class="keyword">switch</span> (msg.what) &#123;</span><br><span class="line">                ......</span><br><span class="line">                <span class="keyword">case</span> STOP_SERVICE:</span><br><span class="line">                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, <span class="string">&quot;serviceStop&quot;</span>);</span><br><span class="line">                    handleStopService((IBinder)msg.obj);</span><br><span class="line">                    schedulePurgeIdler();</span><br><span class="line">                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                ......</span><br><span class="line">            &#125;</span><br><span class="line">            ......</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Handler</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">dispatchMessage</span><span class="params">(<span class="meta">@NonNull</span> Message msg)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (msg.callback != <span class="literal">null</span>) &#123;</span><br><span class="line">            handleCallback(msg);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (mCallback != <span class="literal">null</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (mCallback.handleMessage(msg)) &#123; <span class="comment">//返回false，还会继续执行后面的handleMessage</span></span><br><span class="line">                    <span class="keyword">return</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            handleMessage(msg);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    ......</span><br></pre></td></tr></table></figure>

<p>通过反射替换掉<code>ActivityThread.mH.mCallback</code>，替换后的Callback如下：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//ServiceWatcher.kt</span></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">install</span><span class="params">()</span></span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      swapActivityThreadHandlerCallback &#123; mCallback -&gt;</span><br><span class="line">        uninstallActivityThreadHandlerCallback = &#123;</span><br><span class="line">          swapActivityThreadHandlerCallback &#123;</span><br><span class="line">            mCallback</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        Handler.Callback &#123; msg -&gt;</span><br><span class="line">          <span class="keyword">if</span> (msg.obj !<span class="keyword">is</span> IBinder) &#123;</span><br><span class="line">            <span class="keyword">return</span><span class="symbol">@Callback</span> <span class="literal">false</span> <span class="comment">//返回false后，继续执行H类的消息处理</span></span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          <span class="keyword">if</span> (msg.what == STOP_SERVICE) &#123;</span><br><span class="line">            <span class="keyword">val</span> key = msg.obj <span class="keyword">as</span> IBinder</span><br><span class="line">            activityThreadServices[key]?.let &#123; <span class="comment">//获取service实例</span></span><br><span class="line">              onServicePreDestroy(key, it)</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="comment">//mCallback就是通过反射获取的ActivityThread.mH.mCallback</span></span><br><span class="line">          mCallback?.handleMessage(msg) ?: <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>

<p>通过mH.mCallback只能拿到service的token，并没有拿到service实例。service实例的获取是通过反射获取ActivityThread中的mServices。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">val</span> activityThreadServices <span class="keyword">by</span> lazy &#123;</span><br><span class="line">  <span class="keyword">val</span> mServicesField =</span><br><span class="line">    activityThreadClass.getDeclaredField(<span class="string">&quot;mServices&quot;</span>).apply &#123; isAccessible = <span class="literal">true</span> &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Suppress(<span class="string">&quot;UNCHECKED_CAST&quot;</span>)</span></span><br><span class="line">  mServicesField[activityThreadInstance] <span class="keyword">as</span> Map&lt;IBinder, Service&gt;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过ActivityThread.mH反射方式可以拿到Service的停止事件，这是service stop开始执行的时机，此时可以从<code>ActivityThread.mServices</code>获取到service实例，之后service实例就会从map中删除，就再也拿不到了，这就是分成了onServicePreDestroy和onServiceDestroyed两个阶段的根本原因。</p>
<h3 id="onServiceDestroyed监控Service-destroy"><a href="#onServiceDestroyed监控Service-destroy" class="headerlink" title="onServiceDestroyed监控Service destroy"></a>onServiceDestroyed监控Service destroy</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//frameworks\base\core\java\android\app\ActivityThread.java</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">handleStopService</span><span class="params">(IBinder token)</span> &#123;</span><br><span class="line">        mServicesData.remove(token);</span><br><span class="line">        <span class="type">Service</span> <span class="variable">s</span> <span class="operator">=</span> mServices.remove(token);</span><br><span class="line">        <span class="keyword">if</span> (s != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> (localLOGV) Slog.v(TAG, <span class="string">&quot;Destroying service &quot;</span> + s);</span><br><span class="line">                s.onDestroy();   <span class="comment">//执行Service#onDestroy</span></span><br><span class="line">                s.detachAndCleanUp();</span><br><span class="line">                <span class="type">Context</span> <span class="variable">context</span> <span class="operator">=</span> s.getBaseContext();</span><br><span class="line">                <span class="keyword">if</span> (context <span class="keyword">instanceof</span> ContextImpl) &#123;</span><br><span class="line">                    <span class="keyword">final</span> <span class="type">String</span> <span class="variable">who</span> <span class="operator">=</span> s.getClassName();</span><br><span class="line">                    ((ContextImpl) context).scheduleFinalCleanup(who, <span class="string">&quot;Service&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                QueuedWork.waitToFinish();</span><br><span class="line"></span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="comment">//Service#onDestroy执行完成后的最终时机</span></span><br><span class="line">                    ActivityManager.getService().serviceDoneExecuting(</span><br><span class="line">                            token, SERVICE_DONE_EXECUTING_STOP, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (RemoteException e) &#123;</span><br><span class="line">                    <span class="keyword">throw</span> e.rethrowFromSystemServer();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                <span class="keyword">if</span> (!mInstrumentation.onException(s, e)) &#123;</span><br><span class="line">                    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(</span><br><span class="line">                            <span class="string">&quot;Unable to stop service &quot;</span> + s</span><br><span class="line">                            + <span class="string">&quot;: &quot;</span> + e.toString(), e);</span><br><span class="line">                &#125;</span><br><span class="line">                Slog.i(TAG, <span class="string">&quot;handleStopService: exception for &quot;</span> + token, e);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            Slog.i(TAG, <span class="string">&quot;handleStopService: token=&quot;</span> + token + <span class="string">&quot; not found.&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//Slog.i(TAG, &quot;Running services: &quot; + mServices);</span></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>从上述代码可以看出Service停止最后执行的是<code>ActivityManager.getService().serviceDoneExecuting</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//frameworks\base\core\java\android\app\ActivityManager.java</span></span><br><span class="line"><span class="meta">@SystemService(Context.ACTIVITY_SERVICE)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ActivityManager</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> IActivityManager <span class="title function_">getService</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> IActivityManagerSingleton.get();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Singleton&lt;IActivityManager&gt; IActivityManagerSingleton =</span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">Singleton</span>&lt;IActivityManager&gt;() &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">protected</span> IActivityManager <span class="title function_">create</span><span class="params">()</span> &#123;</span><br><span class="line">                    <span class="keyword">final</span> <span class="type">IBinder</span> <span class="variable">b</span> <span class="operator">=</span> ServiceManager.getService(Context.ACTIVITY_SERVICE);</span><br><span class="line">                    <span class="keyword">final</span> <span class="type">IActivityManager</span> <span class="variable">am</span> <span class="operator">=</span> IActivityManager.Stub.asInterface(b);</span><br><span class="line">                    <span class="keyword">return</span> am;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;;</span><br></pre></td></tr></table></figure>

<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="436px" preserveAspectRatio="none" style="width:572px;height:436px;background:#FFFFFF;" version="1.1" viewBox="0 0 572 436" width="572px" zoomAndPan="magnify"><defs/><g><!--cluster android--><g id="cluster_android"><path d="M211.5,47 L274.5,47 A3.75,3.75 0 0 1 277,49.5 L284,69.2969 L366.5,69.2969 A2.5,2.5 0 0 1 369,71.7969 L369,210.5 A2.5,2.5 0 0 1 366.5,213 L211.5,213 A2.5,2.5 0 0 1 209,210.5 L209,49.5 A2.5,2.5 0 0 1 211.5,47 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="209" x2="284" y1="69.2969" y2="69.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="62" x="213" y="61.9951">android</text></g><!--cluster os--><g id="cluster_os"><path d="M235.5,90 L255.5,90 A3.75,3.75 0 0 1 258,92.5 L265,112.2969 L342.5,112.2969 A2.5,2.5 0 0 1 345,114.7969 L345,186.5 A2.5,2.5 0 0 1 342.5,189 L235.5,189 A2.5,2.5 0 0 1 233,186.5 L233,92.5 A2.5,2.5 0 0 1 235.5,90 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="233" x2="265" y1="112.2969" y2="112.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="19" x="237" y="104.9951">os</text></g><!--class Binder--><g id="elem_Binder"><rect fill="#F1F1F1" height="48" id="Binder" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="79" x="249.5" y="125"/><ellipse cx="264.5" cy="141" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M266.8438,136.6719 C265.9063,136.2344 265.3125,136.0938 264.4375,136.0938 C261.8125,136.0938 259.8125,138.1719 259.8125,140.8906 L259.8125,142.0156 C259.8125,144.5938 261.9219,146.4844 264.8125,146.4844 C266.0313,146.4844 267.1875,146.1875 267.9375,145.6406 C268.5156,145.2344 268.8438,144.7813 268.8438,144.3906 C268.8438,143.9375 268.4531,143.5469 267.9844,143.5469 C267.7656,143.5469 267.5625,143.625 267.375,143.8125 C266.9219,144.2969 266.9219,144.2969 266.7344,144.3906 C266.3125,144.6563 265.625,144.7813 264.8594,144.7813 C262.8125,144.7813 261.5156,143.6875 261.5156,141.9844 L261.5156,140.8906 C261.5156,139.1094 262.7656,137.7969 264.5,137.7969 C265.0781,137.7969 265.6875,137.9531 266.1563,138.2031 C266.6406,138.4844 266.8125,138.7031 266.9063,139.1094 C266.9688,139.5156 267,139.6406 267.1406,139.7656 C267.2813,139.9063 267.5156,140.0156 267.7344,140.0156 C268,140.0156 268.2656,139.875 268.4375,139.6563 C268.5469,139.5 268.5781,139.3125 268.5781,138.8906 L268.5781,137.4688 C268.5781,137.0313 268.5625,136.9063 268.4688,136.75 C268.3125,136.4844 268.0313,136.3438 267.7344,136.3438 C267.4375,136.3438 267.2344,136.4375 267.0156,136.75 L266.8438,136.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="47" x="278.5" y="145.8467">Binder</text><line style="stroke:#181818;stroke-width:0.5;" x1="250.5" x2="327.5" y1="157" y2="157"/><line style="stroke:#181818;stroke-width:0.5;" x1="250.5" x2="327.5" y1="165" y2="165"/></g><!--class IActivityManager--><g id="elem_IActivityManager"><rect codeLine="1" fill="#F1F1F1" height="64.2969" id="IActivityManager" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="182" x="11" y="117"/><ellipse cx="39.95" cy="133" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M40.9031,129.7813 L42.6219,129.7813 C43.0125,129.7813 43.2,129.75 43.325,129.6719 C43.5906,129.5156 43.7313,129.2344 43.7313,128.9375 C43.7313,128.6719 43.6219,128.4063 43.3875,128.2344 C43.2156,128.125 43.075,128.0938 42.6219,128.0938 L37.4813,128.0938 C37.0438,128.0938 36.9188,128.1094 36.7625,128.2031 C36.5125,128.3594 36.3563,128.6563 36.3563,128.9375 C36.3563,129.2188 36.4969,129.4688 36.7156,129.6406 C36.8719,129.75 37.0594,129.7813 37.4813,129.7813 L39.2,129.7813 L39.2,136.2969 L37.4813,136.2969 C37.0438,136.2969 36.9188,136.3125 36.7625,136.4219 C36.5125,136.5781 36.3563,136.8594 36.3563,137.1563 C36.3563,137.4063 36.4969,137.6719 36.7156,137.8281 C36.8719,137.9531 37.075,138 37.4813,138 L42.6219,138 C43.3719,138 43.7313,137.7188 43.7313,137.1563 C43.7313,136.875 43.6219,136.625 43.3875,136.4531 C43.2156,136.3281 43.075,136.2969 42.6219,136.2969 L40.9031,136.2969 L40.9031,129.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="119" x="57.05" y="137.8467">IActivityManager</text><line style="stroke:#181818;stroke-width:0.5;" x1="12" x2="192" y1="149" y2="149"/><line style="stroke:#181818;stroke-width:0.5;" x1="12" x2="192" y1="157" y2="157"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="170" x="17" y="173.9951">serviceDoneExecuting()</text></g><g id="elem_GMN3"><path d="M6,6 L6,31.1328 A0,0 0 0 0 6,31.1328 L98,31.1328 L102,116.853 L106,31.1328 L198,31.1328 A0,0 0 0 0 198,31.1328 L198,16 L188,6 L6,6 A0,0 0 0 0 6,6 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M188,6 L188,16 L198,16 L188,6 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="171" x="12" y="23.0669">&#30001;IActivityManager.aidl&#29983;&#25104;</text></g><!--class Stub--><g id="elem_Stub"><rect codeLine="5" fill="#F1F1F1" height="64.2969" id="Stub" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="182" x="104" y="241"/><ellipse cx="174.75" cy="257" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M176.8281,258.8125 L177.2188,259.7969 L176.8281,259.7969 C176.375,259.7969 176.2656,259.8125 176.1094,259.9219 C175.8594,260.0781 175.7031,260.3594 175.7031,260.6563 C175.7031,260.9219 175.8438,261.1719 176.0625,261.3281 C176.2031,261.4531 176.4063,261.5 176.8281,261.5 L179.1875,261.5 C179.5469,261.5 179.7656,261.4688 179.9063,261.375 C180.1563,261.2344 180.3125,260.9375 180.3125,260.6563 C180.3125,260.375 180.1719,260.125 179.9531,259.9688 C179.7813,259.8281 179.625,259.7969 179.1563,259.7969 L175.7656,251.5938 L172.0938,251.5938 C171.6406,251.5938 171.5156,251.6094 171.3594,251.7031 C171.1094,251.875 170.9531,252.1563 170.9531,252.4375 C170.9531,252.7188 171.0938,252.9688 171.3125,253.1406 C171.4844,253.25 171.6563,253.2813 172.0938,253.2813 L173.1719,253.2813 L170.5313,259.7969 C170.1094,259.7969 169.9531,259.8125 169.7969,259.9219 C169.5469,260.0781 169.3906,260.3594 169.3906,260.6563 C169.3906,261.2188 169.7656,261.5 170.5156,261.5 L172.7813,261.5 C173.1406,261.5 173.3594,261.4688 173.4844,261.375 C173.75,261.2344 173.8906,260.9375 173.8906,260.6563 C173.8906,260.375 173.7656,260.125 173.5469,259.9531 C173.375,259.8281 173.2344,259.7969 172.7813,259.7969 L172.3906,259.7969 L172.7813,258.8125 L176.8281,258.8125 Z M176.125,257.1094 L173.4531,257.1094 L174.7969,253.8438 L176.125,257.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="32" x="195.25" y="261.8467">Stub</text><line style="stroke:#181818;stroke-width:0.5;" x1="105" x2="285" y1="273" y2="273"/><line style="stroke:#181818;stroke-width:0.5;" x1="105" x2="285" y1="281" y2="281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="170" x="110" y="297.9951">serviceDoneExecuting()</text></g><g id="elem_GMN12"><path d="M321.5,253 L321.5,269 L286.289,273 L321.5,277 L321.5,293.2656 A0,0 0 0 0 321.5,293.2656 L448.5,293.2656 A0,0 0 0 0 448.5,293.2656 L448.5,263 L438.5,253 L321.5,253 A0,0 0 0 0 321.5,253 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M438.5,253 L438.5,263 L448.5,263 L438.5,253 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="106" x="327.5" y="270.0669">IActivityManager</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="65" x="327.5" y="285.1997">&#20869;&#37096;&#38745;&#24577;&#31867;</text></g><!--class ActivityManagerService--><g id="elem_ActivityManagerService"><rect fill="#F1F1F1" height="48" id="ActivityManagerService" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="202" x="94" y="373"/><ellipse cx="109" cy="389" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M111.3438,384.6719 C110.4063,384.2344 109.8125,384.0938 108.9375,384.0938 C106.3125,384.0938 104.3125,386.1719 104.3125,388.8906 L104.3125,390.0156 C104.3125,392.5938 106.4219,394.4844 109.3125,394.4844 C110.5313,394.4844 111.6875,394.1875 112.4375,393.6406 C113.0156,393.2344 113.3438,392.7813 113.3438,392.3906 C113.3438,391.9375 112.9531,391.5469 112.4844,391.5469 C112.2656,391.5469 112.0625,391.625 111.875,391.8125 C111.4219,392.2969 111.4219,392.2969 111.2344,392.3906 C110.8125,392.6563 110.125,392.7813 109.3594,392.7813 C107.3125,392.7813 106.0156,391.6875 106.0156,389.9844 L106.0156,388.8906 C106.0156,387.1094 107.2656,385.7969 109,385.7969 C109.5781,385.7969 110.1875,385.9531 110.6563,386.2031 C111.1406,386.4844 111.3125,386.7031 111.4063,387.1094 C111.4688,387.5156 111.5,387.6406 111.6406,387.7656 C111.7813,387.9063 112.0156,388.0156 112.2344,388.0156 C112.5,388.0156 112.7656,387.875 112.9375,387.6563 C113.0469,387.5 113.0781,387.3125 113.0781,386.8906 L113.0781,385.4688 C113.0781,385.0313 113.0625,384.9063 112.9688,384.75 C112.8125,384.4844 112.5313,384.3438 112.2344,384.3438 C111.9375,384.3438 111.7344,384.4375 111.5156,384.75 L111.3438,384.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="170" x="123" y="393.8467">ActivityManagerService</text><line style="stroke:#181818;stroke-width:0.5;" x1="95" x2="295" y1="405" y2="405"/><line style="stroke:#181818;stroke-width:0.5;" x1="95" x2="295" y1="413" y2="413"/></g><!--class ActiveServices--><g id="elem_ActiveServices"><rect codeLine="12" fill="#F1F1F1" height="64.2969" id="ActiveServices" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="234" x="331" y="365"/><ellipse cx="390.75" cy="381" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M393.0938,376.6719 C392.1563,376.2344 391.5625,376.0938 390.6875,376.0938 C388.0625,376.0938 386.0625,378.1719 386.0625,380.8906 L386.0625,382.0156 C386.0625,384.5938 388.1719,386.4844 391.0625,386.4844 C392.2813,386.4844 393.4375,386.1875 394.1875,385.6406 C394.7656,385.2344 395.0938,384.7813 395.0938,384.3906 C395.0938,383.9375 394.7031,383.5469 394.2344,383.5469 C394.0156,383.5469 393.8125,383.625 393.625,383.8125 C393.1719,384.2969 393.1719,384.2969 392.9844,384.3906 C392.5625,384.6563 391.875,384.7813 391.1094,384.7813 C389.0625,384.7813 387.7656,383.6875 387.7656,381.9844 L387.7656,380.8906 C387.7656,379.1094 389.0156,377.7969 390.75,377.7969 C391.3281,377.7969 391.9375,377.9531 392.4063,378.2031 C392.8906,378.4844 393.0625,378.7031 393.1563,379.1094 C393.2188,379.5156 393.25,379.6406 393.3906,379.7656 C393.5313,379.9063 393.7656,380.0156 393.9844,380.0156 C394.25,380.0156 394.5156,379.875 394.6875,379.6563 C394.7969,379.5 394.8281,379.3125 394.8281,378.8906 L394.8281,377.4688 C394.8281,377.0313 394.8125,376.9063 394.7188,376.75 C394.5625,376.4844 394.2813,376.3438 393.9844,376.3438 C393.6875,376.3438 393.4844,376.4375 393.2656,376.75 L393.0938,376.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="106" x="411.25" y="385.8467">ActiveServices</text><line style="stroke:#181818;stroke-width:0.5;" x1="332" x2="564" y1="397" y2="397"/><line style="stroke:#181818;stroke-width:0.5;" x1="332" x2="564" y1="405" y2="405"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="222" x="337" y="421.9951">serviceDoneExecutingLocked()</text></g><!--reverse link IActivityManager to Stub--><g id="link_IActivityManager_Stub"><path codeLine="8" d="M136.6205,195.416 C150.6135,213.772 157.35,222.61 171.335,240.955 " fill="none" id="IActivityManager-backto-Stub" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="125.708,181.101,131.8488,199.0534,141.3921,191.7785,125.708,181.101" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Binder to Stub--><g id="link_Binder_Stub"><path codeLine="9" d="M260.1122,187.4927 C245.4102,206.5747 235.431,219.525 219.228,240.555 " fill="none" id="Binder-backto-Stub" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="271.098,173.234,255.3593,183.8308,264.8651,191.1547,271.098,173.234" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Stub to ActivityManagerService--><g id="link_Stub_ActivityManagerService"><path codeLine="11" d="M195,323.101 C195,344.139 195,353.4806 195,372.6609 " fill="none" id="Stub-backto-ActivityManagerService" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="195,305.101,189,323.101,201,323.101,195,305.101" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ActivityManagerService to ActiveServices--><g id="link_ActivityManagerService_ActiveServices"><path codeLine="15" d="M308.299,397 C319.854,397 319.41,397 330.965,397 " fill="none" id="ActivityManagerService-backto-ActiveServices" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="296.299,397,302.299,401,308.299,397,302.299,393,296.299,397" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[oymhIIrAIqnELV1qJ2x9BCiigVHDp4jCJorIgEPI08BYrAAopEHKb_oyLDUArEJIaioyT0rDhbgklFoIL8MI_0A5_3HClLOApwTiH1VLIynCoNa-PVwpZWbSYKd59KM9oIKAmIMbIOIimZ3UfaPN5woJAp4lfIW_CqKllrZFAJCl1KKExCAYpFIC4f0RmHPPOJWr9kzfM-lBvXKlvyvyrj3uVEDkBh12i2beIeCXxkDApaaiBeP8faB5Yl5umIS_EJir1UmHx0OgQEcYcGO0]--></g></svg>

<p>LeakCanary通过动态代理<code>IActivityManager</code>接口的方式来hook serviceDoneExecuting。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//ServiceWatcher.kt</span></span><br><span class="line"><span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">install</span><span class="params">()</span></span> &#123;</span><br><span class="line">    ......</span><br><span class="line">      swapActivityManager &#123; activityManagerInterface, activityManagerInstance -&gt;</span><br><span class="line">        uninstallActivityManager = &#123;</span><br><span class="line">          swapActivityManager &#123; _, _ -&gt;</span><br><span class="line">            activityManagerInstance</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        Proxy.newProxyInstance(</span><br><span class="line">          activityManagerInterface.classLoader, arrayOf(activityManagerInterface)</span><br><span class="line">        ) &#123; _, method, args -&gt;</span><br><span class="line">          <span class="keyword">if</span> (METHOD_SERVICE_DONE_EXECUTING == method.name) &#123;</span><br><span class="line">            <span class="keyword">val</span> token = args!![<span class="number">0</span>] <span class="keyword">as</span> IBinder</span><br><span class="line">            <span class="keyword">if</span> (servicesToBeDestroyed.containsKey(token)) &#123;</span><br><span class="line">              onServiceDestroyed(token)</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (args == <span class="literal">null</span>) &#123;</span><br><span class="line">              method.invoke(activityManagerInstance)</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">              method.invoke(activityManagerInstance, *args)</span><br><span class="line">            &#125;</span><br><span class="line">          &#125; <span class="keyword">catch</span> (invocationException: InvocationTargetException) &#123;</span><br><span class="line">            <span class="keyword">throw</span> invocationException.targetException</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    ......</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">onServiceDestroyed</span><span class="params">(token: <span class="type">IBinder</span>)</span></span> &#123;</span><br><span class="line">    servicesToBeDestroyed.remove(token)?.also &#123; serviceWeakReference -&gt;</span><br><span class="line">      serviceWeakReference.<span class="keyword">get</span>()?.let &#123; service -&gt;</span><br><span class="line">        reachabilityWatcher.expectWeaklyReachable( <span class="comment">//后面步骤就和activity的相同了</span></span><br><span class="line">          service, <span class="string">&quot;<span class="subst">$&#123;service::class.java.name&#125;</span> received Service#onDestroy() callback&quot;</span></span><br><span class="line">        )</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<h2 id="Fragment泄漏监控"><a href="#Fragment泄漏监控" class="headerlink" title="Fragment泄漏监控"></a>Fragment泄漏监控</h2><p>Fragment的监控是先接收onActivityCreated事件，然后通过activity拿到FragmentManager，然后注册FragmentLifecycleCallbacks，通过onFragmentViewDestroyed回调事件来监控fragment view的内存泄漏，通过onFragmentDestroyed回调事件来监控fragment的泄漏。</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="278px" preserveAspectRatio="none" style="width:993px;height:278px;background:#FFFFFF;" version="1.1" viewBox="0 0 993 278" width="993px" zoomAndPan="magnify"><defs/><g><!--class FragmentAndViewModelWatcher--><g id="elem_FragmentAndViewModelWatcher"><rect fill="#F1F1F1" height="48" id="FragmentAndViewModelWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="268" x="338.5" y="7"/><ellipse cx="353.5" cy="23" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M355.8438,18.6719 C354.9063,18.2344 354.3125,18.0938 353.4375,18.0938 C350.8125,18.0938 348.8125,20.1719 348.8125,22.8906 L348.8125,24.0156 C348.8125,26.5938 350.9219,28.4844 353.8125,28.4844 C355.0313,28.4844 356.1875,28.1875 356.9375,27.6406 C357.5156,27.2344 357.8438,26.7813 357.8438,26.3906 C357.8438,25.9375 357.4531,25.5469 356.9844,25.5469 C356.7656,25.5469 356.5625,25.625 356.375,25.8125 C355.9219,26.2969 355.9219,26.2969 355.7344,26.3906 C355.3125,26.6563 354.625,26.7813 353.8594,26.7813 C351.8125,26.7813 350.5156,25.6875 350.5156,23.9844 L350.5156,22.8906 C350.5156,21.1094 351.7656,19.7969 353.5,19.7969 C354.0781,19.7969 354.6875,19.9531 355.1563,20.2031 C355.6406,20.4844 355.8125,20.7031 355.9063,21.1094 C355.9688,21.5156 356,21.6406 356.1406,21.7656 C356.2813,21.9063 356.5156,22.0156 356.7344,22.0156 C357,22.0156 357.2656,21.875 357.4375,21.6563 C357.5469,21.5 357.5781,21.3125 357.5781,20.8906 L357.5781,19.4688 C357.5781,19.0313 357.5625,18.9063 357.4688,18.75 C357.3125,18.4844 357.0313,18.3438 356.7344,18.3438 C356.4375,18.3438 356.2344,18.4375 356.0156,18.75 L355.8438,18.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="236" x="367.5" y="27.8467">FragmentAndViewModelWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="339.5" x2="605.5" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="339.5" x2="605.5" y1="47" y2="47"/></g><!--class AndroidOFragmentDestroyWatcher--><g id="elem_AndroidOFragmentDestroyWatcher"><rect fill="#F1F1F1" height="48" id="AndroidOFragmentDestroyWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="287" x="7" y="115"/><ellipse cx="22" cy="131" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M24.3438,126.6719 C23.4063,126.2344 22.8125,126.0938 21.9375,126.0938 C19.3125,126.0938 17.3125,128.1719 17.3125,130.8906 L17.3125,132.0156 C17.3125,134.5938 19.4219,136.4844 22.3125,136.4844 C23.5313,136.4844 24.6875,136.1875 25.4375,135.6406 C26.0156,135.2344 26.3438,134.7813 26.3438,134.3906 C26.3438,133.9375 25.9531,133.5469 25.4844,133.5469 C25.2656,133.5469 25.0625,133.625 24.875,133.8125 C24.4219,134.2969 24.4219,134.2969 24.2344,134.3906 C23.8125,134.6563 23.125,134.7813 22.3594,134.7813 C20.3125,134.7813 19.0156,133.6875 19.0156,131.9844 L19.0156,130.8906 C19.0156,129.1094 20.2656,127.7969 22,127.7969 C22.5781,127.7969 23.1875,127.9531 23.6563,128.2031 C24.1406,128.4844 24.3125,128.7031 24.4063,129.1094 C24.4688,129.5156 24.5,129.6406 24.6406,129.7656 C24.7813,129.9063 25.0156,130.0156 25.2344,130.0156 C25.5,130.0156 25.7656,129.875 25.9375,129.6563 C26.0469,129.5 26.0781,129.3125 26.0781,128.8906 L26.0781,127.4688 C26.0781,127.0313 26.0625,126.9063 25.9688,126.75 C25.8125,126.4844 25.5313,126.3438 25.2344,126.3438 C24.9375,126.3438 24.7344,126.4375 24.5156,126.75 L24.3438,126.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="255" x="36" y="135.8467">AndroidOFragmentDestroyWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="293" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="293" y1="155" y2="155"/></g><g id="elem_GMN5"><path d="M84,234.5 L84,259.6328 A0,0 0 0 0 84,259.6328 L217,259.6328 A0,0 0 0 0 217,259.6328 L217,244.5 L207,234.5 L154.5,234.5 L150.5,163 L146.5,234.5 L84,234.5 A0,0 0 0 0 84,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M207,234.5 L207,244.5 L217,244.5 L207,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="112" x="90" y="251.5669">Android 8.0&#21450;&#20197;&#19978;</text></g><!--class AndroidXFragmentDestroyWatcher--><g id="elem_AndroidXFragmentDestroyWatcher"><rect fill="#F1F1F1" height="48" id="AndroidXFragmentDestroyWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="286" x="329.5" y="115"/><ellipse cx="344.5" cy="131" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M346.8438,126.6719 C345.9063,126.2344 345.3125,126.0938 344.4375,126.0938 C341.8125,126.0938 339.8125,128.1719 339.8125,130.8906 L339.8125,132.0156 C339.8125,134.5938 341.9219,136.4844 344.8125,136.4844 C346.0313,136.4844 347.1875,136.1875 347.9375,135.6406 C348.5156,135.2344 348.8438,134.7813 348.8438,134.3906 C348.8438,133.9375 348.4531,133.5469 347.9844,133.5469 C347.7656,133.5469 347.5625,133.625 347.375,133.8125 C346.9219,134.2969 346.9219,134.2969 346.7344,134.3906 C346.3125,134.6563 345.625,134.7813 344.8594,134.7813 C342.8125,134.7813 341.5156,133.6875 341.5156,131.9844 L341.5156,130.8906 C341.5156,129.1094 342.7656,127.7969 344.5,127.7969 C345.0781,127.7969 345.6875,127.9531 346.1563,128.2031 C346.6406,128.4844 346.8125,128.7031 346.9063,129.1094 C346.9688,129.5156 347,129.6406 347.1406,129.7656 C347.2813,129.9063 347.5156,130.0156 347.7344,130.0156 C348,130.0156 348.2656,129.875 348.4375,129.6563 C348.5469,129.5 348.5781,129.3125 348.5781,128.8906 L348.5781,127.4688 C348.5781,127.0313 348.5625,126.9063 348.4688,126.75 C348.3125,126.4844 348.0313,126.3438 347.7344,126.3438 C347.4375,126.3438 347.2344,126.4375 347.0156,126.75 L346.8438,126.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="254" x="358.5" y="135.8467">AndroidXFragmentDestroyWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="330.5" x2="614.5" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="330.5" x2="614.5" y1="155" y2="155"/></g><g id="elem_GMN10"><path d="M298.5,234.5 L298.5,259.6328 A0,0 0 0 0 298.5,259.6328 L430.5,259.6328 A0,0 0 0 0 430.5,259.6328 L430.5,244.5 L420.5,234.5 L380.239,234.5 L449.066,163 L372.239,234.5 L298.5,234.5 A0,0 0 0 0 298.5,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M420.5,234.5 L420.5,244.5 L430.5,244.5 L420.5,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="111" x="304.5" y="251.5669">AndroidX support</text></g><!--class ViewModelClearedWatcher--><g id="elem_ViewModelClearedWatcher"><rect fill="#F1F1F1" height="48" id="ViewModelClearedWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="225" x="466" y="223"/><ellipse cx="481" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M483.3438,234.6719 C482.4063,234.2344 481.8125,234.0938 480.9375,234.0938 C478.3125,234.0938 476.3125,236.1719 476.3125,238.8906 L476.3125,240.0156 C476.3125,242.5938 478.4219,244.4844 481.3125,244.4844 C482.5313,244.4844 483.6875,244.1875 484.4375,243.6406 C485.0156,243.2344 485.3438,242.7813 485.3438,242.3906 C485.3438,241.9375 484.9531,241.5469 484.4844,241.5469 C484.2656,241.5469 484.0625,241.625 483.875,241.8125 C483.4219,242.2969 483.4219,242.2969 483.2344,242.3906 C482.8125,242.6563 482.125,242.7813 481.3594,242.7813 C479.3125,242.7813 478.0156,241.6875 478.0156,239.9844 L478.0156,238.8906 C478.0156,237.1094 479.2656,235.7969 481,235.7969 C481.5781,235.7969 482.1875,235.9531 482.6563,236.2031 C483.1406,236.4844 483.3125,236.7031 483.4063,237.1094 C483.4688,237.5156 483.5,237.6406 483.6406,237.7656 C483.7813,237.9063 484.0156,238.0156 484.2344,238.0156 C484.5,238.0156 484.7656,237.875 484.9375,237.6563 C485.0469,237.5 485.0781,237.3125 485.0781,236.8906 L485.0781,235.4688 C485.0781,235.0313 485.0625,234.9063 484.9688,234.75 C484.8125,234.4844 484.5313,234.3438 484.2344,234.3438 C483.9375,234.3438 483.7344,234.4375 483.5156,234.75 L483.3438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="193" x="495" y="243.8467">ViewModelClearedWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="467" x2="690" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="467" x2="690" y1="263" y2="263"/></g><!--class AndroidSupportFragmentDestroyWatcher--><g id="elem_AndroidSupportFragmentDestroyWatcher"><rect fill="#F1F1F1" height="48" id="AndroidSupportFragmentDestroyWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="335" x="651" y="115"/><ellipse cx="666" cy="131" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M668.3438,126.6719 C667.4063,126.2344 666.8125,126.0938 665.9375,126.0938 C663.3125,126.0938 661.3125,128.1719 661.3125,130.8906 L661.3125,132.0156 C661.3125,134.5938 663.4219,136.4844 666.3125,136.4844 C667.5313,136.4844 668.6875,136.1875 669.4375,135.6406 C670.0156,135.2344 670.3438,134.7813 670.3438,134.3906 C670.3438,133.9375 669.9531,133.5469 669.4844,133.5469 C669.2656,133.5469 669.0625,133.625 668.875,133.8125 C668.4219,134.2969 668.4219,134.2969 668.2344,134.3906 C667.8125,134.6563 667.125,134.7813 666.3594,134.7813 C664.3125,134.7813 663.0156,133.6875 663.0156,131.9844 L663.0156,130.8906 C663.0156,129.1094 664.2656,127.7969 666,127.7969 C666.5781,127.7969 667.1875,127.9531 667.6563,128.2031 C668.1406,128.4844 668.3125,128.7031 668.4063,129.1094 C668.4688,129.5156 668.5,129.6406 668.6406,129.7656 C668.7813,129.9063 669.0156,130.0156 669.2344,130.0156 C669.5,130.0156 669.7656,129.875 669.9375,129.6563 C670.0469,129.5 670.0781,129.3125 670.0781,128.8906 L670.0781,127.4688 C670.0781,127.0313 670.0625,126.9063 669.9688,126.75 C669.8125,126.4844 669.5313,126.3438 669.2344,126.3438 C668.9375,126.3438 668.7344,126.4375 668.5156,126.75 L668.3438,126.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="303" x="680" y="135.8467">AndroidSupportFragmentDestroyWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="652" x2="985" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="652" x2="985" y1="155" y2="155"/></g><g id="elem_GMN17"><path d="M773.5,234.5 L773.5,259.6328 A0,0 0 0 0 773.5,259.6328 L863.5,259.6328 A0,0 0 0 0 863.5,259.6328 L863.5,244.5 L853.5,234.5 L822.5,234.5 L818.5,163 L814.5,234.5 L773.5,234.5 A0,0 0 0 0 773.5,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><path d="M853.5,234.5 L853.5,244.5 L863.5,244.5 L853.5,234.5 " fill="#FEFFDD" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="779.5" y="251.5669">support.v4</text></g><!--reverse link FragmentAndViewModelWatcher to AndroidOFragmentDestroyWatcher--><g id="link_FragmentAndViewModelWatcher_AndroidOFragmentDestroyWatcher"><path codeLine="1" d="M391.2328,58.7523 C337.3148,76.5023 274.463,97.192 220.51,114.953 " fill="none" id="FragmentAndViewModelWatcher-backto-AndroidOFragmentDestroyWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="402.631,55,395.6811,53.0768,391.2328,58.7523,398.1827,60.6756,402.631,55" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link FragmentAndViewModelWatcher to AndroidXFragmentDestroyWatcher--><g id="link_FragmentAndViewModelWatcher_AndroidXFragmentDestroyWatcher"><path codeLine="3" d="M472.5,67 C472.5,84.658 472.5,96.941 472.5,114.678 " fill="none" id="FragmentAndViewModelWatcher-backto-AndroidXFragmentDestroyWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="472.5,55,468.5,61,472.5,67,476.5,61,472.5,55" style="stroke:#181818;stroke-width:1.0;"/></g><!--link AndroidXFragmentDestroyWatcher to ViewModelClearedWatcher--><g id="link_AndroidXFragmentDestroyWatcher_ViewModelClearedWatcher"><path codeLine="5" d="M495.5,163 C513.158,180.6584 533.1984,200.6981 550.9354,218.4357 " fill="none" id="AndroidXFragmentDestroyWatcher-to-ViewModelClearedWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="555.178,222.6784,551.6426,213.486,551.6425,219.1428,545.9857,219.1427,555.178,222.6784" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link FragmentAndViewModelWatcher to AndroidSupportFragmentDestroyWatcher--><g id="link_FragmentAndViewModelWatcher_AndroidSupportFragmentDestroyWatcher"><path codeLine="6" d="M559.0506,58.5152 C616.9866,76.2652 685.297,97.192 743.272,114.953 " fill="none" id="FragmentAndViewModelWatcher-backto-AndroidSupportFragmentDestroyWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="547.577,55,552.1421,60.5821,559.0506,58.5152,554.4855,52.9331,547.577,55" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[SojAJCzDpIjnp4i9oqmjzyrFISq9Jon9paWjKj3IrLK0YXVbPwRukq7LkQGMbnJbLqALSENbbwGg9EMNbEJdAkId4L1j1PDNiD0pUDhVzMJtqYSxkhZSY7D214bEY23WX0Y5ujA2WloY4Yxy6XHqTUqKuCvopabDB4fDWLbDfCk38JQHv7wyUXIiOAxNApC10000]--></g></svg>

<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">internal</span> <span class="keyword">class</span> <span class="title class_">AndroidOFragmentDestroyWatcher</span>(</span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">val</span> reachabilityWatcher: ReachabilityWatcher</span><br><span class="line">) : (Activity) -&gt; <span class="built_in">Unit</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">val</span> fragmentLifecycleCallbacks = <span class="keyword">object</span> : FragmentManager.FragmentLifecycleCallbacks() &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onFragmentViewDestroyed</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">      fm: <span class="type">FragmentManager</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">      fragment: <span class="type">Fragment</span></span></span></span><br><span class="line"><span class="params"><span class="function">    )</span></span> &#123;</span><br><span class="line">      <span class="keyword">val</span> view = fragment.view</span><br><span class="line">      <span class="keyword">if</span> (view != <span class="literal">null</span>) &#123;</span><br><span class="line">        reachabilityWatcher.expectWeaklyReachable(</span><br><span class="line">          view, <span class="string">&quot;<span class="subst">$&#123;fragment::class.java.name&#125;</span> received Fragment#onDestroyView() callback &quot;</span> +</span><br><span class="line">          <span class="string">&quot;(references to its views should be cleared to prevent leaks)&quot;</span></span><br><span class="line">        )</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onFragmentDestroyed</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">      fm: <span class="type">FragmentManager</span>,</span></span></span><br><span class="line"><span class="params"><span class="function">      fragment: <span class="type">Fragment</span></span></span></span><br><span class="line"><span class="params"><span class="function">    )</span></span> &#123;</span><br><span class="line">      reachabilityWatcher.expectWeaklyReachable(</span><br><span class="line">        fragment, <span class="string">&quot;<span class="subst">$&#123;fragment::class.java.name&#125;</span> received Fragment#onDestroy() callback&quot;</span></span><br><span class="line">      )</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">invoke</span><span class="params">(activity: <span class="type">Activity</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> fragmentManager = activity.fragmentManager</span><br><span class="line">    fragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, <span class="literal">true</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="ViewModel泄漏监控"><a href="#ViewModel泄漏监控" class="headerlink" title="ViewModel泄漏监控"></a>ViewModel泄漏监控</h3><p>在AndroidXFragmentDestroyWatcher中初始化ViewModel的泄漏监控。<code>ViewModelClearedWatcher</code>继承自ViewModel。</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="328px" preserveAspectRatio="none" style="width:603px;height:328px;background:#FFFFFF;" version="1.1" viewBox="0 0 603 328" width="603px" zoomAndPan="magnify"><defs/><g><!--class ViewModel--><g id="elem_ViewModel"><rect codeLine="1" fill="#F1F1F1" height="64.2969" id="ViewModel" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="129" x="61" y="7"/><ellipse cx="85" cy="23" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M87.0781,24.8125 L87.4688,25.7969 L87.0781,25.7969 C86.625,25.7969 86.5156,25.8125 86.3594,25.9219 C86.1094,26.0781 85.9531,26.3594 85.9531,26.6563 C85.9531,26.9219 86.0938,27.1719 86.3125,27.3281 C86.4531,27.4531 86.6563,27.5 87.0781,27.5 L89.4375,27.5 C89.7969,27.5 90.0156,27.4688 90.1563,27.375 C90.4063,27.2344 90.5625,26.9375 90.5625,26.6563 C90.5625,26.375 90.4219,26.125 90.2031,25.9688 C90.0313,25.8281 89.875,25.7969 89.4063,25.7969 L86.0156,17.5938 L82.3438,17.5938 C81.8906,17.5938 81.7656,17.6094 81.6094,17.7031 C81.3594,17.875 81.2031,18.1563 81.2031,18.4375 C81.2031,18.7188 81.3438,18.9688 81.5625,19.1406 C81.7344,19.25 81.9063,19.2813 82.3438,19.2813 L83.4219,19.2813 L80.7813,25.7969 C80.3594,25.7969 80.2031,25.8125 80.0469,25.9219 C79.7969,26.0781 79.6406,26.3594 79.6406,26.6563 C79.6406,27.2188 80.0156,27.5 80.7656,27.5 L83.0313,27.5 C83.3906,27.5 83.6094,27.4688 83.7344,27.375 C84,27.2344 84.1406,26.9375 84.1406,26.6563 C84.1406,26.375 84.0156,26.125 83.7969,25.9531 C83.625,25.8281 83.4844,25.7969 83.0313,25.7969 L82.6406,25.7969 L83.0313,24.8125 L87.0781,24.8125 Z M86.375,23.1094 L83.7031,23.1094 L85.0469,19.8438 L86.375,23.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="77" x="101" y="27.8467">ViewModel</text><line style="stroke:#181818;stroke-width:0.5;" x1="62" x2="189" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="62" x2="189" y1="47" y2="47"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="67" y="63.9951">void onCleared()</text></g><!--class ViewModelClearedWatcher--><g id="elem_ViewModelClearedWatcher"><rect codeLine="4" fill="#F5DEB3" height="48" id="ViewModelClearedWatcher" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="225" x="13" y="132"/><ellipse cx="28" cy="148" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M30.3438,143.6719 C29.4063,143.2344 28.8125,143.0938 27.9375,143.0938 C25.3125,143.0938 23.3125,145.1719 23.3125,147.8906 L23.3125,149.0156 C23.3125,151.5938 25.4219,153.4844 28.3125,153.4844 C29.5313,153.4844 30.6875,153.1875 31.4375,152.6406 C32.0156,152.2344 32.3438,151.7813 32.3438,151.3906 C32.3438,150.9375 31.9531,150.5469 31.4844,150.5469 C31.2656,150.5469 31.0625,150.625 30.875,150.8125 C30.4219,151.2969 30.4219,151.2969 30.2344,151.3906 C29.8125,151.6563 29.125,151.7813 28.3594,151.7813 C26.3125,151.7813 25.0156,150.6875 25.0156,148.9844 L25.0156,147.8906 C25.0156,146.1094 26.2656,144.7969 28,144.7969 C28.5781,144.7969 29.1875,144.9531 29.6563,145.2031 C30.1406,145.4844 30.3125,145.7031 30.4063,146.1094 C30.4688,146.5156 30.5,146.6406 30.6406,146.7656 C30.7813,146.9063 31.0156,147.0156 31.2344,147.0156 C31.5,147.0156 31.7656,146.875 31.9375,146.6563 C32.0469,146.5 32.0781,146.3125 32.0781,145.8906 L32.0781,144.4688 C32.0781,144.0313 32.0625,143.9063 31.9688,143.75 C31.8125,143.4844 31.5313,143.3438 31.2344,143.3438 C30.9375,143.3438 30.7344,143.4375 30.5156,143.75 L30.3438,143.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="193" x="42" y="152.8467">ViewModelClearedWatcher</text><line style="stroke:#181818;stroke-width:0.5;" x1="14" x2="237" y1="164" y2="164"/><line style="stroke:#181818;stroke-width:0.5;" x1="14" x2="237" y1="172" y2="172"/></g><!--class ViewModelStoreOwner--><g id="elem_ViewModelStoreOwner"><rect codeLine="6" fill="#F1F1F1" height="64.2969" id="ViewModelStoreOwner" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="285" x="255" y="7"/><ellipse cx="312.75" cy="23" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M313.7031,19.7813 L315.4219,19.7813 C315.8125,19.7813 316,19.75 316.125,19.6719 C316.3906,19.5156 316.5313,19.2344 316.5313,18.9375 C316.5313,18.6719 316.4219,18.4063 316.1875,18.2344 C316.0156,18.125 315.875,18.0938 315.4219,18.0938 L310.2813,18.0938 C309.8438,18.0938 309.7188,18.1094 309.5625,18.2031 C309.3125,18.3594 309.1563,18.6563 309.1563,18.9375 C309.1563,19.2188 309.2969,19.4688 309.5156,19.6406 C309.6719,19.75 309.8594,19.7813 310.2813,19.7813 L312,19.7813 L312,26.2969 L310.2813,26.2969 C309.8438,26.2969 309.7188,26.3125 309.5625,26.4219 C309.3125,26.5781 309.1563,26.8594 309.1563,27.1563 C309.1563,27.4063 309.2969,27.6719 309.5156,27.8281 C309.6719,27.9531 309.875,28 310.2813,28 L315.4219,28 C316.1719,28 316.5313,27.7188 316.5313,27.1563 C316.5313,26.875 316.4219,26.625 316.1875,26.4531 C316.0156,26.3281 315.875,26.2969 315.4219,26.2969 L313.7031,26.2969 L313.7031,19.7813 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="161" x="333.25" y="27.8467">ViewModelStoreOwner</text><line style="stroke:#181818;stroke-width:0.5;" x1="256" x2="539" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="256" x2="539" y1="47" y2="47"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="273" x="261" y="63.9951">ViewModelStore getViewModelStore()</text></g><!--class FragmentActivity--><g id="elem_FragmentActivity"><rect fill="#F1F1F1" height="48" id="FragmentActivity" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="158" x="410.5" y="132"/><ellipse cx="425.5" cy="148" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M427.8438,143.6719 C426.9063,143.2344 426.3125,143.0938 425.4375,143.0938 C422.8125,143.0938 420.8125,145.1719 420.8125,147.8906 L420.8125,149.0156 C420.8125,151.5938 422.9219,153.4844 425.8125,153.4844 C427.0313,153.4844 428.1875,153.1875 428.9375,152.6406 C429.5156,152.2344 429.8438,151.7813 429.8438,151.3906 C429.8438,150.9375 429.4531,150.5469 428.9844,150.5469 C428.7656,150.5469 428.5625,150.625 428.375,150.8125 C427.9219,151.2969 427.9219,151.2969 427.7344,151.3906 C427.3125,151.6563 426.625,151.7813 425.8594,151.7813 C423.8125,151.7813 422.5156,150.6875 422.5156,148.9844 L422.5156,147.8906 C422.5156,146.1094 423.7656,144.7969 425.5,144.7969 C426.0781,144.7969 426.6875,144.9531 427.1563,145.2031 C427.6406,145.4844 427.8125,145.7031 427.9063,146.1094 C427.9688,146.5156 428,146.6406 428.1406,146.7656 C428.2813,146.9063 428.5156,147.0156 428.7344,147.0156 C429,147.0156 429.2656,146.875 429.4375,146.6563 C429.5469,146.5 429.5781,146.3125 429.5781,145.8906 L429.5781,144.4688 C429.5781,144.0313 429.5625,143.9063 429.4688,143.75 C429.3125,143.4844 429.0313,143.3438 428.7344,143.3438 C428.4375,143.3438 428.2344,143.4375 428.0156,143.75 L427.8438,143.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="126" x="439.5" y="152.8467">FragmentActivity</text><line style="stroke:#181818;stroke-width:0.5;" x1="411.5" x2="567.5" y1="164" y2="164"/><line style="stroke:#181818;stroke-width:0.5;" x1="411.5" x2="567.5" y1="172" y2="172"/></g><!--class ViewModelStore1--><g id="elem_ViewModelStore1"><rect codeLine="10" fill="#F1F1F1" height="64.2969" id="ViewModelStore1" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="275" x="321" y="257"/><ellipse cx="395.75" cy="273" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M398.0938,268.6719 C397.1563,268.2344 396.5625,268.0938 395.6875,268.0938 C393.0625,268.0938 391.0625,270.1719 391.0625,272.8906 L391.0625,274.0156 C391.0625,276.5938 393.1719,278.4844 396.0625,278.4844 C397.2813,278.4844 398.4375,278.1875 399.1875,277.6406 C399.7656,277.2344 400.0938,276.7813 400.0938,276.3906 C400.0938,275.9375 399.7031,275.5469 399.2344,275.5469 C399.0156,275.5469 398.8125,275.625 398.625,275.8125 C398.1719,276.2969 398.1719,276.2969 397.9844,276.3906 C397.5625,276.6563 396.875,276.7813 396.1094,276.7813 C394.0625,276.7813 392.7656,275.6875 392.7656,273.9844 L392.7656,272.8906 C392.7656,271.1094 394.0156,269.7969 395.75,269.7969 C396.3281,269.7969 396.9375,269.9531 397.4063,270.2031 C397.8906,270.4844 398.0625,270.7031 398.1563,271.1094 C398.2188,271.5156 398.25,271.6406 398.3906,271.7656 C398.5313,271.9063 398.7656,272.0156 398.9844,272.0156 C399.25,272.0156 399.5156,271.875 399.6875,271.6563 C399.7969,271.5 399.8281,271.3125 399.8281,270.8906 L399.8281,269.4688 C399.8281,269.0313 399.8125,268.9063 399.7188,268.75 C399.5625,268.4844 399.2813,268.3438 398.9844,268.3438 C398.6875,268.3438 398.4844,268.4375 398.2656,268.75 L398.0938,268.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="416.25" y="277.8467">ViewModelStore</text><line style="stroke:#181818;stroke-width:0.5;" x1="322" x2="595" y1="289" y2="289"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="263" x="327" y="305.9951">HashMap&lt;String, ViewModel&gt; mMap</text><line style="stroke:#181818;stroke-width:0.5;" x1="322" x2="595" y1="313.2969" y2="313.2969"/></g><!--class ViewModelStore2--><g id="elem_ViewModelStore2"><rect codeLine="15" fill="#F1F1F1" height="64.2969" id="ViewModelStore2" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="275" x="7" y="257"/><ellipse cx="81.75" cy="273" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M84.0938,268.6719 C83.1563,268.2344 82.5625,268.0938 81.6875,268.0938 C79.0625,268.0938 77.0625,270.1719 77.0625,272.8906 L77.0625,274.0156 C77.0625,276.5938 79.1719,278.4844 82.0625,278.4844 C83.2813,278.4844 84.4375,278.1875 85.1875,277.6406 C85.7656,277.2344 86.0938,276.7813 86.0938,276.3906 C86.0938,275.9375 85.7031,275.5469 85.2344,275.5469 C85.0156,275.5469 84.8125,275.625 84.625,275.8125 C84.1719,276.2969 84.1719,276.2969 83.9844,276.3906 C83.5625,276.6563 82.875,276.7813 82.1094,276.7813 C80.0625,276.7813 78.7656,275.6875 78.7656,273.9844 L78.7656,272.8906 C78.7656,271.1094 80.0156,269.7969 81.75,269.7969 C82.3281,269.7969 82.9375,269.9531 83.4063,270.2031 C83.8906,270.4844 84.0625,270.7031 84.1563,271.1094 C84.2188,271.5156 84.25,271.6406 84.3906,271.7656 C84.5313,271.9063 84.7656,272.0156 84.9844,272.0156 C85.25,272.0156 85.5156,271.875 85.6875,271.6563 C85.7969,271.5 85.8281,271.3125 85.8281,270.8906 L85.8281,269.4688 C85.8281,269.0313 85.8125,268.9063 85.7188,268.75 C85.5625,268.4844 85.2813,268.3438 84.9844,268.3438 C84.6875,268.3438 84.4844,268.4375 84.2656,268.75 L84.0938,268.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="102.25" y="277.8467">ViewModelStore</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="281" y1="289" y2="289"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="263" x="13" y="305.9951">HashMap&lt;String, ViewModel&gt; mMap</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="281" y1="313.2969" y2="313.2969"/></g><!--class Fragment--><g id="elem_Fragment"><rect fill="#F1F1F1" height="48" id="Fragment" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="102" x="273.5" y="132"/><ellipse cx="288.5" cy="148" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M290.8438,143.6719 C289.9063,143.2344 289.3125,143.0938 288.4375,143.0938 C285.8125,143.0938 283.8125,145.1719 283.8125,147.8906 L283.8125,149.0156 C283.8125,151.5938 285.9219,153.4844 288.8125,153.4844 C290.0313,153.4844 291.1875,153.1875 291.9375,152.6406 C292.5156,152.2344 292.8438,151.7813 292.8438,151.3906 C292.8438,150.9375 292.4531,150.5469 291.9844,150.5469 C291.7656,150.5469 291.5625,150.625 291.375,150.8125 C290.9219,151.2969 290.9219,151.2969 290.7344,151.3906 C290.3125,151.6563 289.625,151.7813 288.8594,151.7813 C286.8125,151.7813 285.5156,150.6875 285.5156,148.9844 L285.5156,147.8906 C285.5156,146.1094 286.7656,144.7969 288.5,144.7969 C289.0781,144.7969 289.6875,144.9531 290.1563,145.2031 C290.6406,145.4844 290.8125,145.7031 290.9063,146.1094 C290.9688,146.5156 291,146.6406 291.1406,146.7656 C291.2813,146.9063 291.5156,147.0156 291.7344,147.0156 C292,147.0156 292.2656,146.875 292.4375,146.6563 C292.5469,146.5 292.5781,146.3125 292.5781,145.8906 L292.5781,144.4688 C292.5781,144.0313 292.5625,143.9063 292.4688,143.75 C292.3125,143.4844 292.0313,143.3438 291.7344,143.3438 C291.4375,143.3438 291.2344,143.4375 291.0156,143.75 L290.8438,143.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="70" x="302.5" y="152.8467">Fragment</text><line style="stroke:#181818;stroke-width:0.5;" x1="274.5" x2="374.5" y1="164" y2="164"/><line style="stroke:#181818;stroke-width:0.5;" x1="274.5" x2="374.5" y1="172" y2="172"/></g><!--reverse link ViewModel to ViewModelClearedWatcher--><g id="link_ViewModel_ViewModelClearedWatcher"><path codeLine="5" d="M125.5,89.121 C125.5,108.278 125.5,114.423 125.5,131.884 " fill="none" id="ViewModel-backto-ViewModelClearedWatcher" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="125.5,71.121,119.5,89.121,131.5,89.121,125.5,71.121" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ViewModelStoreOwner to FragmentActivity--><g id="link_ViewModelStoreOwner_FragmentActivity"><path codeLine="9" d="M433.6417,85.1765 C448.9677,104.3335 457.039,114.423 471.007,131.884 " fill="none" id="ViewModelStoreOwner-backto-FragmentActivity" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="422.397,71.121,428.9565,88.9247,438.3269,81.4283,422.397,71.121" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link FragmentActivity to ViewModelStore1--><g id="link_FragmentActivity_ViewModelStore1"><path codeLine="13" d="M481.2655,191.7965 C476.2245,213.0975 471.468,233.2008 465.894,256.7562 " fill="none" id="FragmentActivity-backto-ViewModelStore1" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="484.029,180.119,478.7547,185.0365,481.2655,191.7965,486.5397,186.8789,484.029,180.119" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="473.7204" y="199.9092">1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="8" x="458.5622" y="245.9824">1</text></g><!--reverse link ViewModelStoreOwner to Fragment--><g id="link_ViewModelStoreOwner_Fragment"><path codeLine="18" d="M368.0981,86.3176 C355.9371,105.4746 350.257,114.423 339.174,131.884 " fill="none" id="ViewModelStoreOwner-backto-Fragment" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="377.745,71.121,363.0325,83.102,373.1636,89.5333,377.745,71.121" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Fragment to ViewModelStore2--><g id="link_Fragment_ViewModelStore2"><path codeLine="19" d="M283.0314,187.1801 C253.6614,208.5541 219.495,233.4201 187.096,256.9996 " fill="none" id="Fragment-backto-ViewModelStore2" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="292.734,180.119,285.529,180.4153,283.0314,187.1801,290.2364,186.8838,292.734,180.119" style="stroke:#181818;stroke-width:1.0;"/></g><!--link ViewModelClearedWatcher to ViewModelStore1--><g id="link_ViewModelClearedWatcher_ViewModelStore1"><path codeLine="21" d="M184.267,180.119 C238.601,201.493 308.592,229.027 368.53,252.6065 " fill="none" id="ViewModelClearedWatcher-to-ViewModelStore1" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="379.697,256.9996,375.5779,251.0807,368.53,252.6065,372.6492,258.5254,379.697,256.9996" style="stroke:#181818;stroke-width:1.0;"/></g><!--link ViewModelClearedWatcher to ViewModelStore2--><g id="link_ViewModelClearedWatcher_ViewModelStore2"><path codeLine="22" d="M128.853,180.119 C131.943,201.42 134.8298,221.325 138.2458,244.8804 " fill="none" id="ViewModelClearedWatcher-to-ViewModelStore2" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="139.968,256.7562,143.0655,250.2442,138.2458,244.8804,135.1483,251.3924,139.968,256.7562" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="137.5" y="223.0669">&#28155;&#21152;&#21040;</text></g><!--SRC=[IqmgBYbAJ2vHICv9B2vM2CjCBVVDJqdDKQZcKW22ilpC58NyFEUSrCIYr1GDJQvQBZI5KAdmn9BaZDGY1UNmZDJ44Yw4EJOrkhguL7DbvfMa5gKb9gSYL0INv1Ub-fVd0Ss2E05LHY4zjGHL1EmeRDfjQlJq5DoA4jDpK_DA79DBCiioIogXpbT2rQ2aa5YCPf4Xr7gFnE8CtyG2c-2IeioyT1s4AZk5NA0uq6vqAnIK39KKj82-1j5eXd8HRRyHqVOJz3lSXM1NeLd3nOKhAdLrjJ2SJxnQ8mKhXMVRTp_jMl2qOmC0]--></g></svg>

<p>FragmentActivity和Fragment都是ViewModelStoreOwner，所以在两者的create时机都会创建<code>ViewModelClearedWatcher</code>，并注册。ViewModelClearedWatcher本身也是一个ViewModel，当<code>ViewModelClearedWatcher#onCleared</code>被调用时，<code>ViewModelStoreOwner</code>中注册的ViewModel都会被clear。所以onCleared时，通过反射拿到<code>ViewModelStore#mMap</code>，将map中所有的ViewModel进行泄漏监控。</p>
<h2 id="RootView泄漏监控"><a href="#RootView泄漏监控" class="headerlink" title="RootView泄漏监控"></a>RootView泄漏监控</h2><p><code>RootViewWatcher</code>实现了对RootView内存泄漏的监控。原理是：<code>WindowManagerGlobal#mViews</code>就是存放DecorView的列表，通过反射把mViews替换为自定义的ArrayList。然后在<code>WindowManagerGlobal#addView</code>和<code>WindowManagerGlobal#removeView</code>就可以执行到自定义ArrayList的add和remove方法，从而得到RootView的添加和删除时机，从而触发内存泄漏检测逻辑。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">class</span> <span class="title class_">WindowManagerGlobal</span> &#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> ArrayList&lt;View&gt; mViews = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;View&gt;();</span><br><span class="line">    ......</span><br><span class="line">    <span class="meta">@UnsupportedAppUsage</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> WindowManagerGlobal <span class="title function_">getInstance</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">synchronized</span> (WindowManagerGlobal.class) &#123;</span><br><span class="line">            <span class="keyword">if</span> (sDefaultWindowManager == <span class="literal">null</span>) &#123;</span><br><span class="line">                sDefaultWindowManager = <span class="keyword">new</span> <span class="title class_">WindowManagerGlobal</span>();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> sDefaultWindowManager;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>RootViewWatcher会监听rootView的添加时机，然后调用<code>rootView.addOnAttachStateChangeListener</code>来接收onViewAttachedToWindow和onViewDetachedFromWindow事件。当onViewDetachedFromWindow时就会去检测是否发生内存泄漏。</p>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.csdn.net/gdutxiaoxu/article/details/80738581">java 源码系列 - 带你读懂 Reference 和 ReferenceQueue</a></p>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/Android/" rel="tag"># Android</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/posts/48a4fa29.html" rel="prev" title="Handler源码解析">
                  <i class="fa fa-angle-left"></i> Handler源码解析
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/posts/23659d3d.html" rel="next" title="ARouter源码分析">
                  ARouter源码分析 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">Jason</span>
  </div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener external nofollow noreferrer" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener external nofollow noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.umd.js" integrity="sha256-oyhjPiYRWGXaAt+ny/mTMWOnN1GBoZDUQnzzgC7FRI4=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.5.0/mermaid.min.js","integrity":"sha256-K7oJiQlDulzl24ZUFOywuYme1JqBBvQzK6m8qHjt9Gk="}}</script>
  <script type="module" src="/js/zenuml-definition-074a43fa.js"></script>
  <script type="module" src="/js/mermaid-zenuml.esm.min.mjs"></script>
  <script src="/js/third-party/tags/mermaid.js"></script>


  <script src="/js/third-party/fancybox.js"></script>



  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
